Angular 4: How to view an object for changes?

ETA: I know that there are various ways to see my form of change. This is not what I'm trying to do. As the name says, I ask how to track changes in an object. The application shown below is for illustration purposes only. Please answer the question I asked. Thanks!

I have this simple application:

import { Component, OnInit } from '@angular/core'; export class Customer { firstName: string; favoriteColor: string; } @Component({ selector: 'my-app', template: ` <div *ngIf="customer"> <input type="text" [(ngModel)]="customer.firstName"> <input type="text" [(ngModel)]="customer.favoriteColor"> </div> ` }) export class AppComponent implements OnInit { private customer: Customer; ngOnInit(): void { this.customer = new Customer(); // TODO: how can I register a callback that will run whenever // any property of this.customer has been changed? } } 

Pay attention to TODO. I need to register a callback that will be executed whenever any this.customer property is this.customer .

I cannot use ngChange on inputs. I need to subscribe directly to changes to the model. The reasons relate to my precedent and should not be included here. Just believe me, this is not an option.

Is it possible? I did a lot of googling, but I came up with a dry one.

+18
javascript angular typescript
source share
6 answers

Angular usually uses the KeyValueDiffers class built into the constructor.

For your case, it might look like this:

 import { KeyValueChanges, KeyValueDiffer, KeyValueDiffers } from '@angular/core'; export class Customer { firstName: string; favoriteColor: string; } @Component({ selector: 'my-app', templateUrl: './app.component.html' }) export class AppComponent { private customerDiffer: KeyValueDiffer<string, any>; private customer: Customer; constructor(private differs: KeyValueDiffers) {} ngOnInit(): void { this.customer = new Customer(); this.customerDiffer = this.differs.find(this.customer).create(); } customerChanged(changes: KeyValueChanges<string, any>) { console.log('changes'); /* If you want to see details then use changes.forEachRemovedItem((record) => ...); changes.forEachAddedItem((record) => ...); changes.forEachChangedItem((record) => ...); */ } ngDoCheck(): void { const changes = this.customerDiffer.diff(this.customer); if (changes) { this.customerChanged(changes); } } } 

Stackblitz example

Another option is to use setter for the properties you want to check.

see also

+24
source share

I need to subscribe directly to changes to the model.

Then you need to listen to the model changes using ngModelChange

Template:

 <input type="text" (ngModelChange)="doSomething($event)" [ngModel]="customer.firstName"> 

Grade :

 doSomething(event) { console.log(event); // logs model value } 

Demo

+20
source share

You cannot view changes to an object. Its not angular 1 there are no observers. Another solution would be via observables.

use form

 <form #f="ngForm"> <input type="text" name="firstName" [(ngModel)]="customer.firstName"> <input type="text" name="favoriteColor" [(ngModel)]="customer.favoriteColor"> </form> 

in code

 @ViewChild('f') f; ngAfterViewInit() { this.f.form.valueChanges.subscribe((change) => { console.log(change) }) } 
+8
source share

You can use custom setters to trigger a callback:

 class Customer { private _firstName: string get firstName(): string { return this._firstName } set firstName(firstName: string) { this.valueChanged(this._firstName, firstName) this._firstName = firstName } private _lastName: string get lastName(): string { return this._lastName } set lastName(lastName: string) { this.valueChanged(this._lastName, lastName) this._lastName = lastName } valueChanged: (oldVal, newVal) => void constructor (valueChanged?: (oldVal, newVal) => void) { // return an empty function if no callback was provided in case you don't need // one or want to assign it later this.valueChanged = valueChanged || (() => {}) } } 

Then just assign a callback when creating the object:

 this.customer = new Customer((oldVal, newVal) => console.log(oldVal, newVal)) // or this.customer = new Customer() this.customer.valueChanged = (oldVal, newVal) => console.log(oldVal, newVal) 
+2
source share

visit https://github.com/cartant/rxjs-observe . based on rxjs and proxies.

 import { observe } from "rxjs-observe"; const instance = { name: "Alice" }; const { observables, proxy } = observe(instance); observables.name.subscribe(value => console.log(name)); proxy.name = "Bob"; 
+1
source share

You can see this article, maybe it will help.

 constructor(private ref: ChangeDetectorRef) {} removeSomthing(){ this.items.split(idx, 1); // run manually watcher this.ref.detectChanges(); } 
0
source share

All Articles