Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 2 - [(ngModel)] not updating after [value] changes

I'm setting the the value of an input calculating two other ngModels, and that seems to be working fine. But if I inspect my ngModel, it doesn't change at all. Let me show you:

<ion-item>
    <ion-label>Total price: {{product.totalPrice}}</ion-label>
    <ion-input 
        type="number"
        [value]="product.quantity * product.price"
        [(ngModel)]="product.totalPrice" 
        [ngModelOptions]="{ standalone: true }"></ion-input>
</ion-item>

So here {{product.totalPrice}} shows the initial value, which is fine. If I change manually that input, the changes will be reflected on the expression, that is also fine. But that input will be readonly and it will be set by changing two other inputs. When I change them, I see the value on the input is updating just fine, but not the expression in the label. What's wrong there?

It's really weird because the value in the input GETS UPDATED, but not the expression {{product.totalPrice}}, I guess the value is updating because the other fields are, but those value changes never actually hit the ngModel

By the way, I'm using Ionic 2

like image 381
Agustín Avatar asked Jan 11 '17 22:01

Agustín


People also ask

How do I update my ngModel value?

If we use two way binding syntax for ngModel the value will be updated. So the default (ngModelChange) function will update the value of ngModel property. i.e., user.Name . And the second (ngModelChange) will be triggered printing the user name value in the console.

What does [( ngModel )] do?

The ngModel directive is a directive that is used to bind the values of the HTML controls (input, select, and textarea) or any custom form controls, and stores the required user value in a variable and we can use that variable whenever we require that value. It also is used during form validations.

Is ngModel property binding?

NgModel is a directive that creates the FormControl instance from a domain model and binds it to a form control element. It uses two kinds of binding: Property binding.

Which module do you need to import to use [( ngModel )]?

NgModule: Module used by NgModel is: FormsModule.


2 Answers

Actually [] means bind data and () mean emit changes / or let say raise an event with these changes form this UI control <ion-input>. So [()] doesn't mean two way data binding. It means:

  • bind data using []
  • raise input changes ().

Check this example it shows many ways of binding data with input and how to raise changes.

like image 157
bunjeeb Avatar answered Oct 07 '22 00:10

bunjeeb


So I know that I'm late to the party, but seeing as none of the other answers are correct, I thought I'd add the solution in case anyone else ends up on this page.

When creating a custom component that accepts ngModel, the component must implement the ControlValueAccessor interface. Which is detailed below

interface ControlValueAccessor {  
  writeValue(obj: any): void
  registerOnChange(fn: any): void
  registerOnTouched(fn: any): void
  setDisabledState(isDisabled: boolean): void
}

In order to register a change made by the component, the component must call the onChange method provided by the registerOnChange method.

For example, if we register our onChange method like so:

 onChange: any = () => { };
 registerOnChange(fn) {
   this.onChange = (obj) => fn(obj);
 }

When ever our component makes a change to the value, we must execute the following line

this.onChange(this.value)

Hopes this helps.

Edit

When I first answered this question, for some reason I was under the impression that a custom child component was not updating the parent component. Rereading it now, it seems that either there was an issue with the ionic-input or the OP was incorrectly using it.

This answer better suits how one would create a component and have it update a property of it's parent using NgModel

like image 24
Lewis Campbell Avatar answered Oct 07 '22 00:10

Lewis Campbell