13
votes

Can someone please tell me what is the best practice for comparing ngModel old and new value?

In angular 1:

$scope.$watch('someProperty', funciton(oldVal, newVal){
    // code goes here
})

I am asking this because (ngModelChange) never brings me the oldVal , only the newVal.

In my case, I am using ngModel in a <select> tag and compare the old selection with the new one:

<select [(ngModel)]="current" (ngModelChange)="onModelChange($event)">
     <option *ngFor="let item of myArray" [ngValue]="item">{{item.name}} </option>
</select>
3

3 Answers

17
votes

This might work

(ngModelChange)="onModelChange(oldVal, $event); oldVal = $event;"

or

(ngModelChange)="onModelChange($event)"
oldValue:string;
onModelChange(event) {
  if(this.oldValue != event) {
    ...
  }
  this.oldValue = event;
}
9
votes

Just for the future

we need to observe that [(ngModel)]="hero.name" is just a short-cut that can be de-sugared to: [ngModel]="hero.name" (ngModelChange)="hero.name = $event".

So if we de-sugar code we would end up with:

<select (ngModelChange)="onModelChange()" [ngModel]="hero.name" (ngModelChange)="hero.name = $event">

or

<[ngModel]="hero.name" (ngModelChange)="hero.name = $event" select (ngModelChange)="onModelChange()">

If you inspect the above code you will notice that we end up with 2 ngModelChange events and those need to be executed in some order.

Summing up: If you place ngModelChange before ngModel, you get the $event as the new value, but your model object still holds previous value. If you place it after ngModel, the model will already have the new value.

SOURCE

8
votes

Example with input field...

<div *ngFor="let value of values">{{value}}
    <input [(ngModel)]="value" (focus)="old=value" (ngModelchange)="doSomething(old, value)">
</div>

doSomething(oldVal, newVal) {
    // some code
}