Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular 4: How to watch an object for changes?

ETA: I know that there are various ways to watch my form for changes. That is not what I am trying to do. As the title says, I am asking how to watch for changes to an object. The app shown below is for illustration purposes only. Please answer the question that I have asked. Thanks!

I have this simple app:

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?      }  } 

Note the TODO. I need to register a callback that will run whenever any property of this.customer has been changed.

I cannot use ngChange on the inputs. I need to subscribe directly to changes on the model. The reasons pertain to my use case, and aren't worth going into here. Just trust me that this isn't an option.

Is this possible? I've done a lot of Googling, but I've come up dry.

like image 767
greenie2600 Avatar asked Sep 20 '17 19:09

greenie2600


People also ask

What does object mean in angular?

An object is an instance which contains set of key value pairs. The values can be scalar values or functions or even array of other objects. The syntax is given below −


1 Answers

Angular usually uses injected into constructor KeyValueDiffers class.

For your case it could look like:

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

One more option is using setter on properties that you want to check.

See also

  • http://blog.mgechev.com/2017/11/14/angular-iterablediffer-keyvaluediffer-custom-differ-track-by-fn-performance/
like image 123
yurzui Avatar answered Oct 05 '22 19:10

yurzui