web-dev-qa-db-fra.com

Quelle est la différence entre formControlName et FormControl?

J'utilise ReactiveFormsModule of Angular2 pour créer un composant contenant une fiche. 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 ne peux pas comprendre quelle est la différence entre utiliser [formControl] et formControlName.

70
smartmouse

Je crois que vous avez manqué un point important: [formGroup] directive dans le deuxième exemple. formControlName est utilisé avec [formGroup] pour enregistrer votre formulaire sous plusieurs navigations. 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>

Maintenant, imaginez imbriqué FormGroups :)

125
Harry Ninh

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

formControlName assigne une chaîne au module de formulaires pour rechercher le contrôle par nom.

Si vous créez des variables pour les contrôles, vous n'avez pas non plus besoin du . mentionné par Harry, mais je suggérerais également d'utiliser [formGroup] à la place car 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
    });
}
17
Günter Zöchbauer

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

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

Notez que nous utilisons toujours la directive [formGroup].

Toutefois, pour que ce modèle puisse être compilé sans erreur, votre composant doit déclarer les contrôles en tant que AbstractControls et non FormControls:

monComponent.ts

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

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

5
rmcsharry

De la Angular _ docs ( 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, de la même manière que FormGroup contient un groupe de contrôles, le profileForm FormGroup est lié à l'élément de formulaire avec la directive FormGroup, créant ainsi une couche de communication entre le modèle et le formulaire contenant l'élément. contributions. L'entrée formControlName fournie par la directive FormControlName lie chaque entrée individuelle au contrôle de formulaire défini dans la FormGroup

1
Chris Halcrow

avec [formControl], vous pouvez utiliser les avantages de la programmation réactive, car FormControl possède une propriété nommée valueChanges (je connais celui-ci actuellement, il existe peut-être plus que cela), ce qui retourne un Observable auquel vous pouvez vous inscrire et l'utiliser. (par exemple, il est très utile dans les scénarios de registre pour lesquels vous souhaitez que le courrier électronique saisi ne soit pas répété dès que l'utilisateur modifie la valeur)

0
Seyed Ali Roshan