Quelle est la différence entre formControlName et FormControl?

97

J'utilise ReactiveFormsModuleAngular2 pour créer un composant contenant 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 ne peux pas comprendre quelle est la différence entre l'utilisation [formControl]et formControlName.

souris intelligente
la source
1
Je dirais que la principale raison d'utiliser formControlName sur formControl est lorsque vous ne souhaitez pas conserver des instances de FormControl individuelles dans le composant.
Paul Samsotha

Réponses:

176

Je pense que vous avez manqué un point important: la [formGroup]directive dans le deuxième exemple. formControlNameest utilisé avec [formGroup]pour enregistrer votre formulaire de navigation à plusieurs points. 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:)

Harry Ninh
la source
l'utilisation de [formControl] = "form.get ('Registration.Attributes.aboutme')" a causé des problèmes .. mais fonctionne correctement avec formControlName = "firstNRegistration.Attributes.aboutmeame"
Ricardo Saracino
[formControl]causant un problème lors de la form.validvalidation avec formGroup, tous les commentaires
Pardeep Jain
comment puis-je gérer si l'élément d'entrée est un autre composant. comment lier le fomrcontrol avec le composant
Ramakanth Reddy
20

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

formControlName affecte une chaîne au module Forms pour rechercher le contrôle par son nom.

Si vous créez des variables pour les contrôles, vous n'avez pas non plus besoin du .comme mentionné par Harry, mais je suggérerais également de l'utiliser à la [formGroup]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
    });
}
Günter Zöchbauer
la source
quand j'ajoute this.fullName = new FormControl ('', Validators.required); J'ai eu une erreur comme vous ne pouvez pas l'attribuer car il s'agit d'une propriété ou d'une constante en lecture seule, mais ici, je suis considérée comme une variable.Alors, s'il vous plaît, aidez
user8478
1
Veuillez publier le message d'erreur exact . C'est probablement encore mieux de créer une nouvelle question contenant votre code qui permet de reproduire
Günter Zöchbauer
7

Il y a une 3e é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>

Notez que nous utilisons toujours la directive [formGroup].

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

myComponent.ts

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

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

rmcsharry
la source
comment puis-je gérer si l'élément d'entrée est un autre composant. comment lier le fomrcontrol avec le composant
Ramakanth Reddy
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 d'un composant parent, puis d'un émetteur d'événements). Google comment transmettre des données entre les composants
rmcsharry
pouvez-vous s'il vous plaît regarder ce post stackoverflow.com/questions/58100248/…
Ramakanth Reddy
2

À partir de la documentation 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 FormGroupcontient un groupe de contrôles, le profileForm FormGroupest lié à l'élément de formulaire avec la FormGroup directive, créant une couche de communication entre le modèle et le formulaire contenant les entrées. L' formControlNameentrée fournie par la FormControlNamedirective lie chaque entrée individuelle au contrôle de formulaire défini dans leFormGroup

Chris Halcrow
la source
1

avec [formControl]vous pouvez utiliser les avantages de la programmation réactive car FormControla une propriété nommée valueChanges(je connais celle-ci en ce moment, peut-être qu'il y en a plus que cela) qui retourne un Observableauquel vous pouvez vous abonner et l'utiliser. (par exemple, il est très utile dans les scénarios de registre que vous souhaitez vérifier que l'e-mail d'entrée ne soit pas répété dès que l'utilisateur change la valeur)

Seyed Ali Roshan
la source
Oui. Mais vous utilisez toujours formControlName dans le modèle, même lorsque vous utilisez le modèle dans votre réponse. Affectez simplement le formControlName = "someFormControlName" à un FormControl dans le fichier component.ts comme someFormControlName: FormControl;
Charles Robertson