Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

{{myArray}} array binding not updating in view

import {Component} from "angular2/core";
import {CORE_DIRECTIVES, FORM_DIRECTIVES, FormBuilder, ControlGroup, AbstractControl, Validators, Control} from "angular2/common";

@Component({
    selector: 'parameters-form',
    directives: [FORM_DIRECTIVES,CORE_DIRECTIVES],
    template: `
      <h1>Parameters Form</h1>
      <p [(ngModel)]='arr'>{{ arr }}</p>
      <form [ngFormModel]="myForm" (ngSubmit)="onSubmit(myForm.value)"    class="ui form">

<div class="field">
            <label for="systemParameters">System Parameters</label>
            <input type="number"
                   id="systemParameters"
                   placeholder="systemParameters Param"
                   [ngFormControl]="systemParameters">

            <button type="button" (click)="addToArray(systemParameters.value)">Add</button>

          </div>
<button type="submit" class="ui button">Submit</button>
      </form>
    `
})

export class ParametersForm {
  myForm: ControlGroup;
  systemParameters: AbstractControl;
  arr: number[];
  constructor(fb: FormBuilder) {
    this.myForm = fb.group({
      "realisations" : [""],
      "numConstSteps" : [""],
      "timeHorizon": [""],
      "continuationStep" : [""],
      "continuationStepSign" : [""],
      "numberOfModelParameters" : [""],
      "systemParameters" : [],
      "param" : [""],
      "netLogoFile" : [""],
      "numberOfModelVariables" : [""],
      "restrictOperator" : [""],
      "liftOperator" : [""],
      "xInitial" : [""]

    });
    this.arr = [];
    this.systemParameters = this.myForm.controls["systemParameters"];
  }
  addToArray(value: any): void {
    this.arr.push(value);
    (<Control>this.systemParameters).updateValue("");
  }
  onSubmit(form: any): void {
    console.log(this.arr);
    form.systemParameters = this.arr;
    console.log("your submitted value:", form)
  }

}

i am trying to show the values inside Arr (array) in real-time, when user inputs value in systemParameters field by invoking the Add function which pushes the value to arr array.

this is the error No value accessor for ''" in [arr in ParametersForm@2:9]

its cause from the ngModel thats as much as i know.

Updated: based on Günter's comments I removed both ngModel and Core directives. The {{arr}} contents do not show but internally in the class they do.

like image 369
Petros Kyriakou Avatar asked Sep 17 '26 22:09

Petros Kyriakou


2 Answers

Update: As of beta.16, {{myArray}} will now update in the view, even if the array reference hasn't changed. See also {{myArray}} now updates in the view as of beta.16


Original answer:

Angular change detection compares by value, and for arrays and objects, that means the array or object reference. If your view simply has {{arr} in it, then that binding in the view won't update when you push() items onto the array, because the array reference hasn't changed.

However, normally, a template will loop over the items in an array:

<div *ngFor="item of arr">{{item}}</div>

In this case, Angular change detection will have a binding for each item of the array, so push() updates will be noticed, and the view will be updated.

For debugging, if you instead use {{arr | json}}, you'll also see the view update when you push() onto the array. (This is because the JsonPipe is stateful, which causes Angular change detection to evaluate it every change detection cycle.)

like image 155
Mark Rajcok Avatar answered Sep 20 '26 19:09

Mark Rajcok


Angular change detection doesn't recognize changes within arrays, only changes to the array reference

  addToArray(value: any): void {
    // Angular doesn't recognize this
    this.arr.push(value);
    (<Control>this.systemParameters).updateValue("");
  }

as workaround you can use

  addToArray(value: any): void {
    this.arr.push(value);
    this.arr = this.arr.slice();
    (<Control>this.systemParameters).updateValue("");
  }

to create a copy of the array. Angular recognizes this because the array itself is another one.

Checking for a better way ...

like image 35
Günter Zöchbauer Avatar answered Sep 20 '26 20:09

Günter Zöchbauer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!