У чому різниця між formControlName та FormControl?


97

Я використовую 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 у компоненті.
Пол Самсота

Відповіді:


177

Я вважаю, ви пропустили важливий момент: [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, будь-які коментарі
Pardeep Jain

як я можу впоратися, якщо вхідний елемент - це інший компонент. як зв’язати fomrcontrol із компонентом
Ramakanth Reddy

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.


як я можу впоратися, якщо вхідний елемент - це інший компонент. як зв’язати fomrcontrol із компонентом
Ramakanth Reddy

Ви не можете - навіть якщо Є спосіб, ви не повинні. Елемент повинен бути прив'язаний до елемента управління, визначеного В ТОМУ КОМПОНЕНТІ. Якщо ви хочете передати дані іншому компоненту, скористайтеся послугою (або якщо це батьківський компонент, то випромінювач подій). Google як передавати дані між компонентами
rmcsharry

Ви можете подивитися цю публікацію stackoverflow.com/questions/58100248/…
Рамакант Редді

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

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


Так. Але ви все одно використовуєте formControlName у шаблоні, навіть коли використовуєте модель у своїй відповіді. Просто призначте formControlName = “someFormControlName” FormControl у файлі component.ts, наприклад someFormControlName: FormControl;
Чарльз Робертсон,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.