Angular 4: How to watch an object for changes?

后端 未结 6 800
死守一世寂寞
死守一世寂寞 2021-01-30 20:45

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 change

6条回答
  •  说谎
    说谎 (楼主)
    2021-01-30 21:37

    We are tasked with converting an Angular 1.x app to Angular 9. It's an application with ESRI maps, so we have some neat tools that the ESRI framework brought to the table. ESRI has watchUtils that do a whole lot more than just watch for changes.

    But I missed Angular 1's simple $watch. Besides, we create Entities and Models in our application, and we may need to observe these from time to time.

    I created an abstract class called MappedPropertyClass. It uses a Map to map class properties, which allows me to easily implement toJSON and other utility functions.

    The other Map this class has is _propertyChangeMap: Map;

    We also have a function called... $watch, which takes a string and a callback function.

    This class can be extended by Entities as well as components or services

    I'm happy to share, the caveat is your properties must look like this:

    public get foo(): string {
        return this._get("foo");
    }  
    public set foo(value:string) {
        this._set("foo", value);
    }
    
    
    --------------------------------------------------------------------
    import { EventEmitter } from '@angular/core';
    
    export abstract class MappedPropertyClass {
        private _properties: Map;
        private _propertyChangeMap: Map>;
    
        protected _set(propertyName: string, propertyValue: any) {
            let oldValue = this._get(propertyName);
            this._properties.set(propertyName, propertyValue);
            this.getPropertyChangeEmitter(propertyName).emit({ newvalue: 
        propertyValue, oldvalue: oldValue });
        }
    
        protected _get(propertyName: string): any {
            if (!this._properties.has(propertyName)) {
                this._properties.set(propertyName, undefined);
            } 
            return this._properties.get(propertyName);
        }
    
        protected get properties(): Map {
            var props = new Map();
            for (let key of this._properties.keys()) {
                props.set(key, this._properties.get(key));
            }
    
            return props;
        }
    
        protected constructor() {
            this._properties = new Map();
            this._propertyChangeMap = new Map>();
        }
    
        private getPropertyChangeEmitter(propertyName: string): EventEmitter<{ 
                             newvalue, oldvalue }> {
            if (!this._propertyChangeMap.has(propertyName)) {
                this._propertyChangeMap.set(propertyName, new EventEmitter<{ newvalue, 
                oldvalue }>());
            }
            return this._propertyChangeMap.get(propertyName);
        }
    
        public $watch(propertyName: string, callback: (newvalue, oldvalue) => void): 
        any {
            return this.getPropertyChangeEmitter(propertyName).subscribe((results) => 
            {
                callback(results.newvalue, results.oldvalue);
            });
        }
    }
    

提交回复
热议问题