Значення Angular2, встановлене для formGroup


91

Отже, у мене є складна форма для створення сутності, і я хочу використовувати її для редагування, а також використовую новий 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 api, також я не проти використовувати одностороннє прив'язку даних у шаблоні, як у

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

це працює, але це було б болем у випадку масивів


Наскільки мені відомо, встановлення значення форми наразі не підтримується і буде підтримуватися після наступного оновлення (RC.5). Будь ласка, надайте Plunker.
Günter Zöchbauer

@ GünterZöchbauer перевірити моє поточне рішення
Amgad Serry

Якщо ви подивитесь на: github.com/angular/angular/blob/2.0.0-rc.5/modules/%40angular/… рядок 553 FormGroup.setValue ()?
Климент

Відповіді:


298

Щоб встановити всі значення FormGroup, використовуйте setValue :

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

Щоб встановити лише деякі значення, використовуйте patchValue :

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

За допомогою цієї другої техніки не всі значення потрібно вводити, і поля, чиї значення не були встановлені, не впливатимуть.


1
Я використовую patchValue у вкладеній формі, і він перезаписує всі поля у формі. (навіть ті, кого я не вказую), будь-яке уявлення про те, що я роблю не так?
Enrico

9

Для встановленого значення, коли вашим елементом управління є 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. Це заощадило мій час


5

Ви можете використовувати form.get, щоб отримати конкретний об’єкт управління та використовувати setValue

this.form.get(<formControlName>).setValue(<newValue>);

3

Як зазначалося в коментарях, ця функція не підтримувалась на момент поставлення цього запитання. Ця проблема вирішена в angular 2 rc5


2

Я застосував тимчасове рішення, доки форма підтримки angular2 updateValue

 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 для глибокого клонування jQuery, а також інші бібліотеки.


0

Msgstr "NgModel не працює з новими API 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"
 *  }
 * }
 */

Хоча це виглядає з коментарів TODO , це, швидше за все, буде видалено та замінено реактивним API.

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

що надходить з angular2 api docs NgModel селектор [ngModel]: not ([formControlName]): not ([formControl]) angular.io/docs/ts/latest/api/forms/index/ ... так що навіть якщо він зараз працює, це буде вилучено пізніше, я думаю, що я
застосую

@AmgadSerry, щоб переконатися, що він не заважає цим компонентам (у селекторі). FormControlNameЯвно додає його в якості @Input(). Дивіться джерело, на яке я посилався. Якби цих заперечуючих селекторів не було, тоді з наведеним вище прикладом було б створено NgModel, чого ви не хочете.
Пол Самсота

Це трохи заплутано, але саме так це реалізовано. Для обох FormControlDirective( [formControl]) та FormControlName(formControlName ) це працює так. Якщо ngModelвикористовується без однієї з них, то передбачається, що ви будете використовувати декларативні форми, і NgModelбуде створено. Якщо ngModelвикористовується поряд з однією з директив реактивної форми, тоді ця директива реактивної форми буде обробляти модель, а неNgModel
Paul Samsotha

о, я думав, вони зробили це як хакер, щоб включити ngModel для цих двох директив лише на даний момент, і вони видалять це пізніше
Amgad Serry

перевірити моє поточне рішення
Amgad Serry
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.