Angular2 ตั้งค่าสำหรับ formGroup


93

ดังนั้นฉันจึงมีรูปแบบที่ซับซ้อนสำหรับสร้างเอนทิตีและฉันต้องการใช้เพื่อแก้ไขเช่นกันฉันใช้ API รูปแบบเชิงมุมใหม่ ฉันจัดโครงสร้างแบบฟอร์มให้ตรงกับข้อมูลที่ฉันดึงมาจากฐานข้อมูลดังนั้นฉันจึงต้องการกำหนดค่าของแบบฟอร์มทั้งหมดให้กับข้อมูลที่ดึงมาที่นี่เป็นตัวอย่างของสิ่งที่ฉันต้องการทำ:

this.form = builder.group({
      b : [ "", Validators.required ],
      c : [ "", Validators.required ],
      d : [ "" ],
      e : [ [] ],
      f : [ "" ]
    });
this.form.value({b:"data",c:"data",d:"data",e:["data1","data2"],f:data});

PS: NgModel ใช้ไม่ได้กับ API รูปแบบใหม่และฉันไม่รังเกียจที่จะใช้การผูกข้อมูลทางเดียวในเทมเพลตเช่นเดียวกับใน

<input formControlName="d" value="[data.d]" />

ที่ใช้งานได้ แต่จะเป็นความเจ็บปวดในกรณีของอาร์เรย์


เท่าที่ฉันรู้ว่าการตั้งค่าแบบฟอร์มไม่ได้รับการสนับสนุนในขณะนี้และจะได้รับการสนับสนุนหลังจากการอัปเดตครั้งต่อไป (RC.5) โปรดระบุ Plunker
GünterZöchbauer

@ GünterZöchbauerตรวจสอบโซลูชันปัจจุบันของฉัน
Amgad Serry

คุณดูที่: github.com/angular/angular/blob/2.0.0-rc.5/modules/%40angular/…บรรทัด 553 FormGroup.setValue ()?
Clement

คำตอบ:


304

ในการตั้งค่าFormGroup ทั้งหมดให้ใช้setValue :

this.myFormGroup.setValue({
  formControlName1: myValue1, 
  formControlName2: myValue2
});

หากต้องการตั้งค่าเพียงบางค่าให้ใช้patchValue :

this.myFormGroup.patchValue({
  formControlName1: myValue1, 
  // formControlName2: myValue2 (can be omitted)
});

ด้วยเทคนิคที่สองนี้ไม่จำเป็นต้องใส่ค่าทั้งหมดและช่องที่ไม่ได้ตั้งค่าจะไม่ได้รับผลกระทบ


1
ฉันใช้ patchValue ในรูปแบบที่ซ้อนกันและมีการเขียนทับฟิลด์ทั้งหมดในแบบฟอร์ม (แม้แต่คนที่ฉันไม่ได้ระบุ) มีความคิดว่าฉันทำอะไรผิด?
Enrico

@ Enrico ไม่มีรหัส ur ฉันไม่สามารถช่วยคุณได้
manymanymore

10

สำหรับค่าที่ตั้งไว้เมื่อตัวควบคุมของคุณคือ FormGroup สามารถใช้ตัวอย่างนี้ได้

this.clientForm.controls['location'].setValue({
      latitude: position.coords.latitude,
      longitude: position.coords.longitude
    });


5

ได้คุณสามารถใช้ setValue เพื่อกำหนดค่าสำหรับวัตถุประสงค์ในการแก้ไข / อัปเดต

this.personalform.setValue({
      name: items.name,
      address: {
        city: items.address.city,
        country: items.address.country
      }
    });

คุณสามารถอ้างอิงhttp://musttoknow.com/use-angular-reactive-form-addinsert-update-data-using-setvalue-setpatch/เพื่อทำความเข้าใจวิธีใช้รูปแบบปฏิกิริยาสำหรับคุณสมบัติเพิ่ม / แก้ไขโดยใช้ setValue ช่วยประหยัดเวลาของฉัน


3

ตามที่ระบุไว้ในความคิดเห็นคุณลักษณะนี้ไม่ได้รับการสนับสนุนในขณะที่ถามคำถามนี้ ปัญหานี้ได้รับการแก้ไขแล้วใน angular 2 rc5


2

ฉันได้ใช้วิธีแก้ปัญหาชั่วคราวจนกว่าจะมีการอัปเดตค่าฟอร์มสนับสนุน angular2

 initFormGroup(form: FormGroup, data: any) {
        for(var key in form.controls) {
          console.log(key);
          if(form.controls[key] instanceof FormControl) {
            if(data[key]){
              let control = <FormControl>form.controls[key];
              this.initFormControl(control,data[key]);
            }
          } else if(form.controls[key] instanceof FormGroup) {
            if(data[key]){
              this.initFormGroup(<FormGroup>form.controls[key],data[key]);
            }
          } else if(form.controls[key] instanceof FormArray) {
            var control = <FormArray>form.controls[key];
            if(data[key])
            this.initFormArray(control, data[key]);
          }
        }
      }
      initFormArray(array: FormArray, data: Array<any>){
    if(data.length>0){
      var clone = array.controls[0];
      array.removeAt(0);
      for(var idx in data) {
        array.push(_.cloneDeep(clone));
        if(clone instanceof FormGroup)
          this.initFormGroup(<FormGroup>array.controls[idx], data[idx]);
        else if(clone instanceof FormControl)
          this.initFormControl(<FormControl>array.controls[idx], data[idx]);
        else if(clone instanceof FormArray)
          this.initFormArray(<FormArray>array.controls[idx], data[idx]);
      }
    }
  }


initFormControl(control: FormControl, value:any){
    control.updateValue(value);
  }

การใช้งาน:

this.initFormGroup(this.form, {b:"data",c:"data",d:"data",e:["data1","data2"],f:data});

หมายเหตุ: แบบฟอร์มและข้อมูลต้องมีโครงสร้างเดียวกันและฉันใช้ lodash สำหรับ deepcloning jQuery และ libs อื่น ๆ ก็สามารถทำได้เช่นกัน


0

"NgModel ไม่ทำงานกับ API รูปแบบใหม่"

ที่ไม่เป็นความจริง. คุณต้องใช้อย่างถูกต้อง หากคุณใช้รูปแบบปฏิกิริยาควรใช้ NgModel ร่วมกับคำสั่งรีแอคทีฟ ดูตัวอย่างในแหล่งที่มา

/*
 * @Component({
 *      selector: "login-comp",
 *      directives: [REACTIVE_FORM_DIRECTIVES],
 *      template: `
 *        <form [formGroup]="myForm" (submit)='onLogIn()'>
 *          Login <input type='text' formControlName='login' [(ngModel)]="credentials.login">
 *          Password <input type='password' formControlName='password'
 *                          [(ngModel)]="credentials.password">
 *          <button type='submit'>Log in!</button>
 *        </form>
 *      `})
 * class LoginComp {
 *  credentials: {login:string, password:string};
 *  myForm = new FormGroup({
 *    login: new Control(this.credentials.login),
 *    password: new Control(this.credentials.password)
 *  });
 *
 *  onLogIn(): void {
 *    // this.credentials.login === "some login"
 *    // this.credentials.password === "some password"
 *  }
 * }
 */

แม้ว่าจะดูเหมือนจากความคิดเห็นสิ่งที่ต้องทำแต่ก็มีแนวโน้มที่จะถูกลบและแทนที่ด้วย reactive API

// TODO(kara):  Replace ngModel with reactive API
@Input('ngModel') model: any;

มาจาก angular2 api docs NgModel selector [ngModel]: not ([formControlName]): not ([formControl]) angular.io/docs/ts/latest/api/forms/index/…ดังนั้นแม้ว่ามันจะใช้งานได้ในตอนนี้ แต่ก็จะเป็น ลบออกในภายหลังฉันคิดว่าฉันจะใช้หัวฉีดค่าด้วยตนเองเนื่องจากจะเป็นโซลูชันที่มีเสถียรภาพมากขึ้น
Amgad Serry

@AmgadSerry นั่นคือเพื่อให้แน่ใจว่าจะไม่รบกวนส่วนประกอบเหล่านั้น (ในตัวเลือก) เพิ่มอย่างชัดเจนว่ามันเป็นFormControlName @Input()ดูแหล่งที่มาที่ฉันเชื่อมโยง หากไม่มีตัวเลือกที่ปฏิเสธเหล่านั้นจากตัวอย่างด้านบนระบบจะสร้าง NgModel ขึ้นมาซึ่งคุณไม่ต้องการ
Paul Samsotha

มันสับสนเล็กน้อย แต่นั่นเป็นเพียงวิธีการใช้งาน สำหรับทั้งFormControlDirective( [formControl]) และFormControlName( formControlName) นี่คือวิธีการทำงาน หากngModelมีการใช้โดยไม่มีหนึ่งในนั้นจะถือว่าคุณกำลังใช้แบบฟอร์มที่เปิดเผยและNgModelสร้างขึ้น หากngModelถูกนำมาใช้ควบคู่ไปกับหนึ่งในปฏิกิริยาสั่งแบบฟอร์มแล้วว่ารูปแบบคำสั่งปฏิกิริยาจะจัดการรูปแบบที่ไม่ได้เป็นNgModel
พอล Samsotha

โอ้ฉันคิดว่าพวกเขาทำเช่นนั้นเป็นการแฮ็กเพื่อเปิดใช้งาน ngModel ในคำสั่งทั้งสองนี้ในขณะนี้เท่านั้นและพวกเขาจะลบออกในภายหลัง
Amgad Serry

ตรวจสอบโซลูชันปัจจุบันของฉัน
Amgad Serry
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.