В чем разница между formControlName и FormControl?

Я использую ReactiveFormsModule Angular2, чтобы создать компонент, который содержит форму. Вот мой код:

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.htmlformControlName):

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

5 ответов

Решение

Я считаю, что вы упустили важный момент: [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 назначает строку для модуля форм для поиска элемента управления по имени.

Если вы создаете переменные для элементов управления, вам также не нужно . как упомянуто Гарри, но я бы также предложил использовать [formGroup] вместо этого, потому что с более сложными формами это может стать грязным.

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

Существует 3-я эквивалентность двум, указанным в принятом ответе, а именно (не рекомендуется):

<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 не рекомендуется, поэтому, если вы получите ошибку Cannot find control with unspecified name attribute тогда, вероятно, вы смешали стили или объявили свои элементы управления как AbstractControls.

Из угловых документов ( 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 содержит группу элементов управления, profileForm FormGroup связан с элементом формы с FormGroup директива, создающая уровень связи между моделью и формой, содержащей входные данные. formControlName вклад предоставлен FormControlName Директива привязывает каждый отдельный вход к элементу управления формы, определенной в FormGroup

С [formControl] Вы можете использовать преимущества реактивного программирования, потому что FormControl имеет свойство с именем valueChanges (Я знаю это прямо сейчас, может быть, есть нечто большее), который возвращает Observable на который вы можете подписаться и использовать его. (например, это очень полезно в сценариях регистрации, в которых вы хотите проверить, не вводятся ли входящие сообщения электронной почты, как только пользователь изменит значение)

Другие вопросы по тегам