web-dev-qa-db-de.com

Was ist der Unterschied zwischen formControlName und FormControl?

Ich benutze ReactiveFormsModule von Angular2, um eine Komponente zu erstellen, die ein Formular enthält. Hier ist mein Code:

foo.component.ts:

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

foo.component.html (mit [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 (mit 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>

Beide Wege funktionieren. Aber ich kann nicht herausfinden, was der Unterschied zwischen der Verwendung von [formControl] Und formControlName ist.

70
smartmouse

Ich glaube, Sie haben einen wichtigen Punkt übersehen: die Direktive [formGroup] Im zweiten Beispiel. formControlName wird zusammen mit [formGroup] verwendet, um Ihre Formularnavigation mit mehreren Punkten zu speichern. Beispielsweise:

<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>

Ist äquivalent zu:

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

Stellen Sie sich nun geschachteltes FormGroups vor :)

125
Harry Ninh

[formControl] Weist einen Verweis auf die FormControl -Instanz zu, die Sie für FormControlDirective erstellt haben.

formControlName weist dem Formularmodul eine Zeichenfolge zu, um das Steuerelement nach Namen zu suchen.

Wenn Sie Variablen für die Steuerelemente erstellen, benötigen Sie auch nicht das von Harry erwähnte ., Aber ich würde auch vorschlagen, stattdessen [formGroup] Zu verwenden, da dies bei komplizierteren Formularen unübersichtlich werden kann .

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

Es gibt eine dritte Äquivalenz zu den beiden in der akzeptierten Antwort angegebenen:

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

Beachten Sie, dass wir weiterhin die Direktive [formGroup] verwenden.

Damit diese Vorlage jedoch fehlerfrei kompiliert werden kann, muss Ihre Komponente die Steuerelemente als AbstractControls und nicht als FormControls deklarieren:

myComponent.ts

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

Beachten Sie jedoch, dass die Deklaration von AbstractControls nicht empfohlen ist. Wenn Sie also den Fehler Cannot find control with unspecified name attribute dann ist es wahrscheinlich, dass Sie die Stile gemischt haben oder Ihre Steuerelemente als AbstractControls deklariert haben.

5
rmcsharry

Aus den Angular docs ( https://angular.io/guide/reactive-forms ):

Komponente

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

Vorlage

<form [formGroup]="profileForm">

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

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

</form>

Beachten Sie, dass, genau wie das FormGroup eine Gruppe von Steuerelementen enthält, das profileForm FormGroup mit der Direktive FormGroup an das Formularelement gebunden wird, wodurch eine Kommunikationsschicht zwischen dem Modell und dem erstellt wird Formular mit den Eingaben. Die Eingabe formControlName, die von der Direktive FormControlName bereitgestellt wird, bindet jede einzelne Eingabe an das Formularsteuerelement, das in der Anweisung FormGroup definiert ist.

1
Chris Halcrow

mit [formControl] Sie können die Vorteile der reaktiven Programmierung nutzen, da FormControl eine Eigenschaft mit dem Namen valueChanges hat (ich kenne diese derzeit, vielleicht gibt es noch mehr), die eine Observable zurückgibt Sie können es abonnieren und verwenden. (Dies ist beispielsweise in Registrierungsszenarien sehr nützlich, in denen Sie überprüfen möchten, dass die Eingabe-E-Mail nicht wiederholt wird, sobald der Benutzer den Wert ändert.)

0