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


1
ฉันจะบอกว่าเหตุผลหลักในการใช้ formControlName กับ formControl คือเมื่อคุณไม่ต้องการรักษาอินสแตนซ์ FormControl แต่ละรายการในคอมโพเนนต์
Paul Samsotha

คำตอบ:


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"
Ricardo Saracino

[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 = FormControl ใหม่ ('', Validators.required); ฉันได้รับข้อผิดพลาดเช่นคุณไม่สามารถกำหนดได้เนื่องจากเป็นคุณสมบัติแบบอ่านอย่างเดียวหรือค่าคงที่ แต่ที่นี่ฉันถูกใช้เป็นตัวแปรดังนั้นโปรดช่วยด้วย
user8478

1
กรุณาโพสต์ข้อความแสดงข้อผิดพลาดที่แน่นอน อาจจะดีกว่าถ้าสร้างคำถามใหม่ที่มีรหัสของคุณซึ่งอนุญาตให้ทำซ้ำได้
GünterZöchbauer

7

มีการเทียบเคียงที่สามกับทั้งสองที่ระบุไว้ในคำตอบที่ยอมรับซึ่งเป็นสิ่งนี้ (ไม่แนะนำ):

<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/…
Ramakanth Reddy

2

จากเอกสารเชิงมุม ( 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;
Charles Robertson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.