AngularJS में, हम $watch, $digest... का उपयोग करके परिवर्तनशील परिवर्तन सुन सकते हैं, जो अब Angular (5, 6) के नए संस्करणों के साथ संभव नहीं है।

कोणीय में, यह व्यवहार अब घटक जीवनचक्र का हिस्सा है।

मैंने आधिकारिक दस्तावेज़ों, लेखों और विशेष रूप से एंगुलर 5 चेंज डिटेक्शन ऑन म्यूटेबल ऑब्जेक्ट्स पर चेक किया। , यह पता लगाने के लिए कि में चर (वर्ग गुण) परिवर्तन को कैसे सुनना है टाइपस्क्रिप्ट क्लास / Angular

आज क्या प्रस्तावित है:

import { OnChanges, SimpleChanges, DoCheck } from '@angular/core';


@Component({
  selector: 'my-comp',
  templateUrl: 'my-comp.html',
  styleUrls: ['my-comp.css'],
  inputs:['input1', 'input2']
})
export class MyClass implements OnChanges, DoCheck, OnInit{

  //I can track changes for this properties
  @Input() input1:string;
  @Input() input2:string;
  
  //Properties what I want to track !
  myProperty_1: boolean
  myProperty_2: ['A', 'B', 'C'];
  myProperty_3: MysObject;

  constructor() { }

  ngOnInit() { }

  //Solution 1 - fired when Angular detects changes to the @Input properties
  ngOnChanges(changes: SimpleChanges) {
    //Action for change
  }

  //Solution 2 - Where Angular fails to detect the changes to the input property
  //the DoCheck allows us to implement our custom change detection
  ngDoCheck() {
    //Action for change
  }
}

यह केवल @Input() संपत्ति के लिए सही है!

अगर मैं अपने घटक की अपनी संपत्तियों (myProperty_1, myProperty_2 या myProperty_3) के परिवर्तनों को ट्रैक करना चाहता हूं, तो यह काम नहीं करेगा।

क्या कोई इस समस्या को हल करने में मेरी मदद कर सकता है? अधिमानतः एक समाधान जो कोणीय 5 . के साथ संगत है

34
L Y E S - C H I O U K H 29 मार्च 2018, 12:18

4 जवाब

सबसे बढ़िया उत्तर

आप अभी भी KeyValueDiffers द्वारा DoCheck लाइफहुक द्वारा घटक के फ़ील्ड सदस्यों के मूल्य परिवर्तन की जांच कर सकते हैं।

import { DoCheck, KeyValueDiffers, KeyValueDiffer } from '@angular/core';

differ: KeyValueDiffer<string, any>;
constructor(private differs: KeyValueDiffers) {
  this.differ = this.differs.find({}).create();
}

ngDoCheck() {
  const change = this.differ.diff(this);
  if (change) {
    change.forEachChangedItem(item => {
      console.log('item changed', item);
    });
  }
}

डेमो देखें।

23
Ronin 28 जुलाई 2019, 15:14

आप ChangeDetectorRef आयात कर सकते हैं

 constructor(private cd: ChangeDetectorRef) {
          // detect changes on the current component
            // this.cd is an injected ChangeDetector instance
            this.cd.detectChanges();

            // or run change detection for the all app
            // this.appRef is an ApplicationRef instance
            this.appRef.tick();
}
0
Sultan Khan 29 मार्च 2018, 09:56

जैसा कि कहा गया है कि आप उपयोग कर सकते हैं

public set myProperty_2(value: type): void {
 if(value) {
  //doMyCheck
 }

 this._myProperty_2 = value;
}

और फिर यदि आपको इसे पुनः प्राप्त करने की आवश्यकता है

public get myProperty_2(): type {
  return this._myProperty_2;
}

इस तरह आप अपने वेरिएबल्स को सेट/प्राप्त करते समय अपनी इच्छित सभी जांच कर सकते हैं, इस तरह हर बार जब आप myProperty_2 प्रॉपर्टी सेट/प्राप्त करते हैं तो यह विधियां आग लग जाएंगी।

छोटा डेमो: https://stackblitz.com/edit/angular-n72qlu

2
Valex 29 मार्च 2018, 09:55

मुझे लगता है कि आपकी समस्या का सबसे अच्छा समाधान एक डेकोरेटर का उपयोग करना है जो मूल फ़ील्ड को एक संपत्ति के साथ स्वचालित रूप से बदल देता है, फिर सेटर पर आप एक SimpleChanges ऑब्जेक्ट बना सकते हैं जो कोणीय द्वारा बनाए गए समान का उपयोग करने के लिए होता है। कोणीय के लिए अधिसूचना कॉलबैक (वैकल्पिक रूप से आप इन सूचनाओं के लिए एक अलग इंटरफ़ेस बना सकते हैं, लेकिन एक ही सिद्धांत लागू होता है)

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
4
Titian Cernicova-Dragomir 29 मार्च 2018, 11:09