简体   繁体   中英

Angular2 update form control value

I have a problem building dynamic angular2 forms with controls and select boxes, for example this plunker :

    <select class="form-control" ngControl="power">
      <option *ngFor="#p of powers" [value]="p">{{p}}</option>
    </select>

You can select a hero power, and the control will have the same value. But if you press Change Powers , the selected value would be null but the control value is still the old value. This is a serious problem I think as this is a source of a lot of bugs when the form shows one thing but in reality it will submit something different, is there some way to update the content of the control ? There is updateValue() but you have to manually set the value in all those cases.

There is also a similar case when you update the selectbox options after the form building, it will show a selected value in the selectedbox, while the control value would be null, any ideas on how to deal with this ?

In Angular 2 Final (RC5+) there are new APIs for updating form values. The patchValue() API method supports partial form updates, where we only need to specify some of the fields:

this.form.patchValue({id: selected.id})

There is also the setValue() API method that needs an object with all the form fields. If there is a field missing, we will get an error.

Update

as of latest Update of angular2 syntax will be like this

this.form.controls['power'].setValue('anthing here');

Currently this is the only thing you can do (as mentioned in the question)

this.form.controls['power'].updateValue(null);

There is an open issue to allow to reset a form https://github.com/angular/angular/issues/4933

There is also a pull request but that also allows you to to it "manually" for each control but also allows to reset states like pristine, touched, ... https://github.com/angular/angular/pull/6679

[Angular 2 Stable]

Here's a dirty way just using NgModel (and without importing other form-builder or form-group modules)

//
// set form field, "foo" value to "bar"
//

//
// view
//
<form #formRef="ngForm">
    <input name="foo" [(ngModel)]="foo"></input>
</form>

//
// controller
//
class {
    @ViewChild('formRef') form: NgModel;

    ngAfterViewInit() {
        setTimeout(() => {
          this.form['controls']['foo'].setValue('bar');
        });
    }
}

You can try to keep form sort of immutable. When you need to reset it you just rebuild it. This way can be sure it's up to date. You can also keep values stored somewhere and reset form to those values. Say you're editing an item, when you reset you can revert to the original values, not just an empty form...

export class TheForm {
  public form: ControlGroup;
  public controls = (value: any = {}) => ({
    'id': [value.id],
    'name': [value.name, Validators.required]
  });

  constructor() {
    let values = some_values_from_database || {};
    this.build(values);
  }

  build(value) {
    this.form = this._builder.group(this.controls(value));
  }

  submit() {
    console.log(this.form.value);
  }
}

I've created the base form that handles this kind of functionality with @ngrx/store , here's the Gist . When I need a form for different model, I'll extend BaseForm and just define controls and submit() method, the rest is inherited...

代码是:

(<FormControl>this.form.controls['power']).updateValue(data);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM