FormControlName 和 FormControl 有什么区别?

我使用 Angular2的 ReactiveFormsModule来创建一个包含表单的组件:

返回文章页面

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

Html (使用 [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>

Html (使用 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>

两种方法都有效。但是我不知道使用 [formControl]formControlName有什么区别。

114305 次浏览

我相信您忽略了一个重要的问题: 第二个示例中的 [formGroup]指令。formControlName[formGroup]一起使用,可以保存表单的多点导航。例如:

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

相当于:

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

现在想象嵌套的 FormGroups:)

[formControl]FormControlDirective创建的 FormControl实例分配一个引用。

formControlName为 Forms 模块分配一个字符串,以便按名称查找控件。

如果你为控件创建变量,你也不需要像 Harry 提到的那样使用 .,但是我还是建议使用 [formGroup],因为使用更复杂的形式会变得混乱。

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

对于 [formControl],你可以使用响应式编程优势,因为 FormControl有一个名为 valueChanges的属性(我现在知道这个,也许还有更多) ,它返回一个 Observable,你可以订阅并使用它。(例如,它是非常有用的注册场景,你想检查输入电子邮件不重复尽快用户改变值)

在接受的答案中提供了第三个等价物,这就是(不推荐) :

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

注意,我们仍在使用[ formGroup ]指令。

但是,要使该模板编译没有错误,那么您的组件需要将控件声明为 AbstractControls 而不是 FormControls:

我的组件

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

但是,请注意,声明 AbstractControls 是 不推荐,所以如果您得到错误 Cannot find control with unspecified name attribute,那么很可能您已经混合了样式或已经声明您的控件为 AbstractControls。

来自 Angular 文档(https://angular.io/guide/reactive-forms) :

组件

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

模板

<form [formGroup]="profileForm">


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


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


</form>

注意,正如 FormGroup包含一组控件一样, ProfileFormFormGroupFormGroup绑定到 form 元素 方法之间创建一个通信层 提供的 formControlName输入 FormControlName指令将每个单独的输入绑定到表单 在 FormGroup中定义的控件