可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I'm using ReactiveFormsModule
of Angular2 to create a component that contains a form. Here is my code:
foo.component.ts:
constructor(fb: FormBuilder) {
this.myForm = fb.group({
'fullname': ['', Validators.required],
'gender': []
});
}
foo.component.html (with [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 (with 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>
Both ways work. But i cannot figure out what is the difference between using [formControl]
and formControlName
.
回答1:
I believe you missed an important point: [formGroup]
directive in the second example. formControlName
is used together with [formGroup]
to save your form multiple dot navigations. For example:
<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>
Is equivalent to:
<div [formGroup]="myForm">
<input type="text" formControlName="firstName"/>
<input type="text" formControlName="lastName"/>
<input type="text" formControlName="email"/>
<input type="text" formControlName="title"/>
</div>
Now imagine nested FormGroups
:)
回答2:
[formControl]
assigns a reference to the FormControl
instance you created to the FormControlDirective
.
formControlName
assigns a string for the forms module to look up the control by name.
If you create variables for the controls, you also don't need the .
as mentioned by Harry, but I'd also suggest to use [formGroup]
instead because with more complicated forms this can become messy.
constructor(fb: FormBuilder) {
this.fullName = new FormControl('', Validators.required);
this.gender = new FormControl('');
this.myForm = fb.group({
'fullname': this.fullName,
'gender': this.gender
});
}
回答3:
There is a 3rd equivalency to the two provided in the accepted answer, which is this (not recommended):
<div [formGroup]="myForm">
<input type="text" [formControl]="firstName"/>
<input type="text" [formControl]="lastName"/>
<input type="text" [formControl]="email"/>
<input type="text" [formControl]="title"/>
</div>
Notice that we are still using the [formGroup] directive.
However, for this template to compile without error, then your component needs to declare the controls as AbstractControls and not FormControls:
myComponent.ts
firstName: AbstractControl
lastName: AbstractControl
email: AbstractControl
title: AbstractControl
However, please note that declaring AbstractControls is not recommended, so if you get the error Cannot find control with unspecified name attribute
then it is probable you have mixed the styles or have declared your controls as AbstractControls.
回答4:
From the Angular docs (https://angular.io/guide/reactive-forms):
Component
@Component({
...
})
export class ProfileEditorComponent {
profileForm = new FormGroup({
firstName: new FormControl(''),
lastName: new FormControl(''),
});
}
Template
<form [formGroup]="profileForm">
<label>
First Name:
<input type="text" formControlName="firstName">
</label>
<label>
Last Name:
<input type="text" formControlName="lastName">
</label>
</form>
Note that just as the FormGroup
contains a group of controls, the
profileForm FormGroup
is bound to the form element with the FormGroup
directive, creating a communication layer between the model and the
form containing the inputs. The formControlName
input provided by the
FormControlName
directive binds each individual input to the form
control defined in the FormGroup
回答5:
with [formControl]
you can use Reactive programming advantages because FormControl
has a property named valueChanges
(I know this one right now, maybe there is more than that) which returns an Observable
which you can subscribe and use it. (for example, it is very useful in register scenarios which you want to check input email to be not repeated as soon as user change the value)