126 votes

Quelle est la différence entre formControlName et FormControl ?

J'utilise ReactiveFormsModule d'Angular2 pour créer un composant qui contient un formulaire. Voici mon code :

foo.component.ts :

constructor(fb: FormBuilder) {
    this.myForm = fb.group({
        'fullname': ['', Validators.required],
        'gender': []
    });
}

foo.component.html (avec [formControl] ):

<div class="fields">
    <div class="field">
        <label>Fullname*</label>
        <input type="text" [formControl]="myForm.controls.fullname"/>
    </div>
</div>

<div class="inline fields">
    <label for="gender">Gender</label>
    <div class="field">
        <div class="ui radio checkbox">
            <input type="radio" name="gender" checked="" tabindex="0" class="hidden" [formControl]="myForm.controls.gender">
            <label>Male</label>
        </div>
    </div>
    <div class="field">
        <div class="ui radio checkbox">
            <input type="radio" name="gender" tabindex="0" class="hidden" [formControl]="myForm.controls.gender">
            <label>Female</label>
        </div>
    </div>
</div>

foo.component.html (avec formControlName ):

<div class="fields">
    <div class="field">
        <label>Fullname*</label>
        <input type="text" formControlName="fullname"/>
    </div>
</div>

<div class="inline fields">
    <label for="gender">Gender</label>
    <div class="field">
        <div class="ui radio checkbox">
            <input type="radio" name="gender" checked="" tabindex="0" class="hidden" formControlName="gender">
            <label>Male</label>
        </div>
    </div>
    <div class="field">
        <div class="ui radio checkbox">
            <input type="radio" name="gender" tabindex="0" class="hidden" formControlName="gender">
            <label>Female</label>
        </div>
    </div>
</div>

Les deux méthodes fonctionnent. Mais je n'arrive pas à comprendre quelle est la différence entre l'utilisation de [formControl] y formControlName .

1 votes

Je dirais que la raison principale pour utiliser formControlName plutôt que formControl est quand vous ne voulez pas maintenir des instances individuelles de FormControl dans le composant.

219voto

Harry Ninh Points 8106

Je crois que vous avez manqué un point important : [formGroup] dans le deuxième exemple. formControlName est utilisé conjointement avec [formGroup] pour sauvegarder les navigations à points multiples de votre formulaire. Par exemple :

<div>
  <input type="text" [formControl]="myForm.controls.firstName"/>
  <input type="text" [formControl]="myForm.controls.lastName"/>
  <input type="text" [formControl]="myForm.controls.email"/>
  <input type="text" [formControl]="myForm.controls.title"/>
</div>

Est équivalent à :

<div [formGroup]="myForm">
  <input type="text" formControlName="firstName"/>
  <input type="text" formControlName="lastName"/>
  <input type="text" formControlName="email"/>
  <input type="text" formControlName="title"/>
</div>

Imaginez maintenant que vous êtes imbriqués FormGroups :)

1 votes

L'utilisation de [formControl]="form.get('Registration.Attributes.aboutme')" a causé des problèmes, mais fonctionne bien avec formControlName="firstNRegistration.Attributes.aboutmeame".

0 votes

[formControl] causant un problème alors que form.valid validation avec formGroup, commentaires éventuels

0 votes

Comment puis-je gérer le fait que l'élément d'entrée soit un autre composant ? comment puis-je lier le contrôle interne au composant ?

21voto

Günter Zöchbauer Points 21340

[formControl] assigne une référence à la FormControl que vous avez créée vers l'instance FormControlDirective .

formControlName attribue une chaîne pour que le module de formulaires recherche le contrôle par son nom.

Si vous créez des variables pour les contrôles, vous n'avez pas besoin non plus de l'option . comme mentionné par Harry, mais je suggère également d'utiliser [formGroup] parce qu'avec des formulaires plus compliqués, cela peut devenir compliqué.

constructor(fb: FormBuilder) {
    this.fullName = new FormControl('', Validators.required);
    this.gender = new FormControl('');
    this.myForm = fb.group({
        'fullname': this.fullName,
        'gender': this.gender
    });
}

0 votes

Quand j'ajoute this.fullName = new FormControl('', Validators.required) ; j'obtiens une erreur comme vous ne pouvez pas assigner parce qu'il s'agit d'une propriété ou d'une constante en lecture seule, mais ici je suis prise comme une variable.

1 votes

Veuillez afficher le exact message d'erreur. Il est sans doute encore mieux de créer une nouvelle question contenant votre code qui permet de reproduire

8voto

rmcsharry Points 2065

Il existe une 3ème équivalence aux deux fournies dans la réponse acceptée, qui est la suivante (non recommandée) :

<div [formGroup]="myForm">
  <input type="text" [formControl]="firstName"/>
  <input type="text" [formControl]="lastName"/>
  <input type="text" [formControl]="email"/>
  <input type="text" [formControl]="title"/>
</div>

Remarquez que nous utilisons toujours la directive [formGroup].

Cependant, pour que ce modèle compile sans erreur, votre composant doit déclarer les contrôles comme AbstractControls et non FormControls :

moncomposant.ts

firstName: AbstractControl
lastName: AbstractControl
email: AbstractControl
title: AbstractControl

Cependant, veuillez noter que la déclaration de AbstractControls est non recommandé donc si vous obtenez l'erreur Cannot find control with unspecified name attribute alors il est probable que vous ayez mélangé les styles ou que vous ayez déclaré vos contrôles en tant que AbstractControls.

0 votes

Comment puis-je gérer le fait que l'élément d'entrée soit un autre composant ? comment puis-je lier le contrôle interne au composant ?

0 votes

Vous ne pouvez pas - même s'il existe un moyen, vous ne devriez pas. L'élément doit être lié au contrôle défini DANS CE COMPOSANT. Si vous souhaitez transmettre des données à un autre composant, utilisez un service (ou, s'il s'agit du composant parent, un émetteur d'événements). Google comment transmettre des données entre composants

0 votes

Pouvez-vous s'il vous plaît regarder ce post stackoverflow.com/questions/58100248/

2voto

Chris Halcrow Points 907

Dans la documentation d'Angular ( https://angular.io/guide/reactive-forms ):

Composant

@Component({
  ...
})
export class ProfileEditorComponent {
  profileForm = new FormGroup({
    firstName: new FormControl(''),
    lastName: new FormControl(''),
  });
}

Modèle

<form [formGroup]="profileForm">

  <label>
    First Name:
    <input type="text" formControlName="firstName">
  </label>

  <label>
    Last Name:
    <input type="text" formControlName="lastName">
  </label>

</form>

Notez que, tout comme le FormGroup contient un groupe de contrôles, le formulaire de profil FormGroup est lié à l'élément de formulaire avec l'attribut FormGroup créant ainsi une couche de communication entre le modèle et l'interface utilisateur. formulaire contenant les entrées. Le site formControlName la contribution fournie par le FormControlName lie chaque entrée individuelle au contrôle de formulaire défini dans la directive FormGroup

0voto

Seyed Ali Roshan Points 485

Avec [formControl] vous pouvez utiliser les avantages de la programmation réactive car FormControl a une propriété nommée valueChanges (je ne connais que celui-là pour l'instant, il y en a peut-être d'autres) qui renvoie un fichier de type Observable à laquelle vous pouvez vous abonner et l'utiliser. (par exemple, c'est très utile dans les scénarios de registre où vous voulez vérifier l'email d'entrée pour qu'il ne soit pas répété dès que l'utilisateur change la valeur).

0 votes

Oui, mais vous utilisez toujours formControlName dans le modèle, même si vous utilisez le modèle dans votre réponse. Il suffit d'attribuer le formControlName="someFormControlName" à un FormControl dans le fichier component.ts comme someFormControlName : FormControl ;

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X