How to listen for value changes from class property TypeScript - Angular

前端 未结 5 1205
情话喂你
情话喂你 2020-12-13 06:57

In AngularJS, we can listen variable change using $watch, $digest... which is no longer possible with the new versions of Angular (5, 6).

I

5条回答
  •  借酒劲吻你
    2020-12-13 07:31

    I think the nicest solution to your issue is to use a decorator that replaces the original field with a property automatically, then on the setter you can create a SimpleChanges object similar to the one created by angular in order to use the same notification callback as for angular (alternatively you could create a different interface for these notifications, but the same principle applies)

    import { OnChanges, SimpleChanges, DoCheck, SimpleChange } from '@angular/core';
    
    function Watch() : PropertyDecorator & MethodDecorator{
        function isOnChanges(val: OnChanges): val is OnChanges{
            return !!(val as OnChanges).ngOnChanges
        }
        return (target : any, key: string | symbol, propDesc?: PropertyDescriptor) => {
            let privateKey = "_" + key.toString();
            let isNotFirstChangePrivateKey = "_" + key.toString() + 'IsNotFirstChange';
            propDesc = propDesc || {
                configurable: true,
                enumerable: true,
            };
            propDesc.get = propDesc.get || (function (this: any) { return this[privateKey] });
    
            const originalSetter = propDesc.set || (function (this: any, val: any) { this[privateKey] = val });
    
            propDesc.set = function (this: any, val: any) {
                let oldValue = this[key];
                if(val != oldValue) {
                    originalSetter.call(this, val);
                    let isNotFirstChange = this[isNotFirstChangePrivateKey];
                    this[isNotFirstChangePrivateKey] = true;
                    if(isOnChanges(this)) {
                        var changes: SimpleChanges = {
                            [key]: new SimpleChange(oldValue, val, !isNotFirstChange)
                        }
                        this.ngOnChanges(changes);
                    }
                }
            }
            return propDesc;
        }
    }
    
    // Usage
    export class MyClass implements OnChanges {
    
    
        //Properties what I want to track !
        @Watch()
        myProperty_1: boolean  =  true
        @Watch()
        myProperty_2 =  ['A', 'B', 'C'];
        @Watch()
        myProperty_3 = {};
    
        constructor() { }
        ngOnChanges(changes: SimpleChanges) {
            console.log(changes);
        }
    }
    
    var myInatsnce = new MyClass(); // outputs original field setting with firstChange == true
    myInatsnce.myProperty_2 = ["F"]; // will be notified on subsequent changes with firstChange == false
    

提交回复
热议问题