formControlName 和 FormControl 有什么区别?

What is the difference between formControlName and FormControl?

我正在使用 Angular2 的 ReactiveFormsModule 创建一个包含表单的组件。这是我的代码:

foo.component.ts:

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

foo.component.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>

foo.component.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.

有什么区别

我相信您错过了重要的一点:第二个示例中的 [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] 将您创建的 FormControl 实例的引用分配给 FormControlDirective.

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

如果您为控件创建变量,您也不需要 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
    });
}

with [formControl] 你可以使用响应式编程的优势,因为 FormControl 有一个名为 valueChanges 的 属性 (我现在知道这个,也许还有更多) 其中 returns 和 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:

myComponent.ts

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

但是,请注意,声明 AbstractControls 是 not recommended,因此如果您遇到错误 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>

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