Jaka jest różnica między formControlName i FormControl?

100

Używam ReactiveFormsModuleAngular2 do tworzenia komponentu zawierającego formularz. Oto mój kod:

foo.component.ts :

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

foo.component.html (z [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 (z 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>

Oba sposoby działają. Ale nie mogę dowiedzieć się, jaka jest różnica między używaniem [formControl]a formControlName.

inteligentna mysz
źródło
1
Powiedziałbym, że głównym powodem używania formControlName zamiast formControl jest to, że nie chcesz utrzymywać pojedynczych wystąpień FormControl w komponencie.
Paul Samsotha,

Odpowiedzi:

180

Uważam, że pominął pan ważny punkt: [formGroup]dyrektywę w drugim przykładzie. formControlNamejest używany razem z, [formGroup]aby zapisać w formularzu nawigację z wieloma kropkami. Na przykład:

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

Jest równa:

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

Teraz wyobraź sobie zagnieżdżone FormGroups:)

Harry Ninh
źródło
using [formControl] = "form.get ('Registration.Attributes.aboutme')" powodowało problemy .. ale działa dobrze z formControlName = "firstNRegistration.Attributes.aboutmeame"
Ricardo Saracino,
[formControl]powoduje problem podczas form.validwalidacji z formGroup, wszelkie komentarze
Pardeep Jain
jak sobie poradzić, jeśli elent wejściowy jest innym składnikiem. jak połączyć fomrcontrol z komponentem
Ramakanth Reddy
20

[formControl]przypisuje odniesienie do utworzonej FormControlinstancji do FormControlDirective.

formControlName przypisuje ciąg dla modułu formularzy w celu wyszukania kontrolki według nazwy.

Jeśli tworzysz zmienne dla kontrolek, nie potrzebujesz również tego, o .czym wspomniał Harry, ale sugerowałbym również użycie [formGroup]zamiast tego, ponieważ w przypadku bardziej skomplikowanych formularzy może to stać się bałagan.

constructor(fb: FormBuilder) {
    this.fullName = new FormControl('', Validators.required);
    this.gender = new FormControl('');
    this.myForm = fb.group({
        'fullname': this.fullName,
        'gender': this.gender
    });
}
Günter Zöchbauer
źródło
kiedy dodam this.fullName = new FormControl ('', Validators.required); Wystąpił błąd, na przykład nie możesz przypisać, ponieważ jest to właściwość tylko do odczytu lub stała, ale tutaj jestem traktowany jako zmienna, więc proszę o pomoc
user8478
1
Proszę zamieścić dokładny komunikat o błędzie. Prawdopodobnie jeszcze lepiej jest utworzyć nowe pytanie zawierające kod, który pozwala na reprodukcję
Günter Zöchbauer,
7

Istnieje trzecia równoważność z dwoma podanymi w zaakceptowanej odpowiedzi, która jest następująca (niezalecane):

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

Zauważ, że nadal używamy dyrektywy [formGroup].

Jednak aby ten szablon kompilował się bez błędów, komponent musi zadeklarować kontrolki jako AbstractControls, a nie FormControls:

myComponent.ts

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

Należy jednak pamiętać, że deklarowanie AbstractControls nie jest zalecane , więc jeśli Cannot find control with unspecified name attributepojawi się błąd , prawdopodobnie zmieszałeś style lub zadeklarowałeś kontrolki jako AbstractControls.

rmcsharry
źródło
jak sobie poradzić, jeśli elent wejściowy jest innym składnikiem. jak połączyć fomrcontrol z komponentem
Ramakanth Reddy
Nie możesz - nawet jeśli jest sposób, nie powinieneś. Element powinien być powiązany z kontrolką zdefiniowaną W TYM SKŁADNIKU. Jeśli chcesz przekazać dane do innego komponentu, użyj usługi (lub jeśli jest to komponent nadrzędny, to emiter zdarzeń). Google jak przesyłać dane między komponentami
rmcsharry
czy możesz spojrzeć na ten post stackoverflow.com/questions/58100248/…
Ramakanth Reddy
2

Z dokumentacji Angular ( https://angular.io/guide/reactive-forms ):

Składnik

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

Szablon

<form [formGroup]="profileForm">

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

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

</form>

Zwróć uwagę, że tak jak FormGroupzawiera grupę kontrolek, profileForm FormGroupjest powiązany z elementem formularza za pomocą FormGroup dyrektywy, tworząc warstwę komunikacyjną między modelem a formularzem zawierającym dane wejściowe. Dane formControlNamewejściowe dostarczone przez FormControlNamedyrektywę wiążą poszczególne dane wejściowe z kontrolką formularza zdefiniowaną wFormGroup

Chris Halcrow
źródło
1

z [formControl]tobą możesz skorzystać z zalet programowania reaktywnego, ponieważ FormControlma właściwość o nazwie valueChanges(znam tę w tej chwili, może jest więcej niż to), która zwraca wartość, Observablektórą możesz subskrybować i używać. (na przykład jest to bardzo przydatne w scenariuszach rejestrów, w których chcesz sprawdzić, czy wejściowy e-mail nie jest powtarzany, gdy tylko użytkownik zmieni wartość)

Seyed Ali Roshan
źródło
Tak. Ale nadal używasz formControlName w szablonie, nawet jeśli używasz modelu w swojej odpowiedzi. Po prostu przypisz formControlName = „someFormControlName” do elementu FormControl w pliku component.ts, np. SomeFormControlName: FormControl;
Charles Robertson,