I've an angular application, with the following component code
export class AppComponent {
length: number = 200;
width: number = 150;
height: number = 100;
margin: number = 5;
fingerSize: number = 10;
thickness: number = 3;
doSomethingOnChange(){
//...
}
}
Each property is bound with 2-way binding:
<div style="display: flex">
<div>
<span>Width</span>
<input type="number" [(ngModel)]="width" />
</div>
<div>
<span>Length</span>
<input type="number" [(ngModel)]="length" />
</div>
<div>
<span>Height</span>
<input type="number" [(ngModel)]="height" />
</div>
<div>
<span>Thickness</span>
<input type="number" [(ngModel)]="thickness" />
</div>
<div>
<span>Finger size</span>
<input type="number" [(ngModel)]="fingerSize" />
</div>
<div>
<span>Margin</span>
<input type="number" [(ngModel)]="margin" />
</div>
</div>
I would like to call my method doSomethingOnChange()
every time the user make any changes to those values. Is there a way?
I tried to implement the onChanges interface but the method was still not called on updates. Any idea of what I'm missing?
CodePudding user response:
You can use getter/setter to intercept interactions with given fields. ngOnChanges will be called only for mutations of @Input/@Output
fields
export class AppComponent {
_length: number = 200;
get length(){
doSomethingOnLengthRead();
return this._length;
}
set length(v:number){
doSomethingOnLengthWrite(v);
this._length=v;
}
}
alot of boilerplate will be generated, but will do the trick.
CodePudding user response:
Just add (change)="doSomethingOnChange()" to each input.
<input type="number" [(ngModel)]="width" (change)="doSomethingOnChange()" />
This will fire the event once the value is committed to the model.
OR , if you want to trigger every time user interacts with the input, you could do instead:
<input type="number" [ngModel]="width" (ngModelChange)="doSomethingOnChange()"/>
CodePudding user response:
An alternative is to add (ngModelChange)="doSomethingOnChange($event)"
to your form element. From the NgModel docs:
Event emitter for producing the ngModelChange event after the view model updates.
Your HTML might then look something like:
<div style="display: flex">
<div>
<span>Width</span>
<input type="number" [ngModel]="width" (ngModelChange)="handleWidthChange($event)" />
</div>
<div>
<span>Length</span>
<input type="number" [ngModel]="length" (ngModelChange)="handleLengthChange($event)" />
</div>
<div>
<span>Height</span>
<input type="number" [ngModel]="height" (ngModelChange)="handleHeightChange($event)" />
</div>
<div>
<span>Thickness</span>
<input type="number" [ngModel]="thickness" (ngModelChange)="handleThicknessChange($event)" />
</div>
<div>
<span>Finger size</span>
<input type="number" [ngModel]="fingerSize" (ngModelChange)="handleFingerSizeChange($event)" />
</div>
<div>
<span>Margin</span>
<input type="number" [ngModel]="margin" (ngModelChange)="handleMarginChange($event)" />
</div>
</div>
You'll just want to make sure that you are setting the value that is then bound back to your form element. Ex:
handleWidthChange(event: any) {
this.width = event;
}
Should result in less boilerplate code than the getter/setter method if using template-driven forms.
CodePudding user response:
Have you tried <input type="number" [(ngModel)]="width" (change)="doSomethingOnChange($event)" />
?
or you could use ReactiveFormsModule by creating a FormGroup and subscribe the form. For example,
myForm: FormGroup = new FormGroup({
width: new FormControl(this.width, [Validators.required]),
height: new FormControl(this.height, [Validators.required]),
..........
});
this.myForm.valueChanges.subscribe(v => { doSomethingOnChange() })
<div [formGroup]="myForm">
<input type="number" formControlName="width"/>
......
</div>