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

99

Я использую ReactiveFormsModuleAngular2 для создания компонента, содержащего форму. Вот мой код:

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.

умная мышь
источник
1
Я бы сказал, что основная причина использования formControlName вместо formControl - это когда вы не хотите поддерживать отдельные экземпляры FormControl в компоненте.
Пол Самсота,

Ответы:

179

Я считаю, что вы упустили важный момент: [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] = "form.get ('Registration.Attributes.aboutme')" вызвало проблемы .. но отлично работает с formControlName = "firstNRegistration.Attributes.aboutmeame"
Рикардо Сарачино
[formControl]вызывает проблему при form.validпроверке с помощью formGroup, любые комментарии
Пардип Джайн
как я могу справиться, если входной элемент является другим компонентом. как связать fomrcontrol с компонентом
Рамакант Редди
20

[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
    });
}
Гюнтер Цёхбауэр
источник
когда я добавляю this.fullName = new FormControl ('', Validators.required); У меня ошибка типа вы не можете назначить, потому что это свойство или константа только для чтения, но здесь я принимаюсь за переменную, поэтому, пожалуйста, помогите
user8478
1
Отправьте точное сообщение об ошибке. Вероятно, даже лучше создать новый вопрос, содержащий ваш код, который позволяет воспроизводить
Günter Zöchbauer
7

Существует 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.

rmcsharry
источник
как я могу справиться, если входной элемент является другим компонентом. как связать fomrcontrol с компонентом
Рамакант Редди
Вы не можете - даже если есть способ, вы не должны. Элемент должен быть привязан к элементу управления, определенному В ЭТОМ КОМПОНЕНТЕ. Если вы хотите передать данные другому компоненту, используйте службу (или, если это родительский компонент, то эмиттер событий). Google, как передавать данные между компонентами
rmcsharry
Рамакант Редди
2

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

Крис Хэлкроу
источник
1

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

Сейед Али Рошан
источник
Да. Но вы по-прежнему используете formControlName в шаблоне, даже если используете модель в своем ответе. Просто назначьте formControlName = «someFormControlName» объекту FormControl в файле component.ts, например someFormControlName: FormControl;
Чарльз Робертсон