typescript 检测组件输入的嵌套属性的更改

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/36267119/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 03:22:49  来源:igfitidea点击:

detect change of nested property for component input

typescriptangular

提问by Xaver

In a simplified way I have an Angular2 Component and an input object like this:

以一种简化的方式,我有一个 Angular2 组件和一个像这样的输入对象:

class MyObject{
 Prop1:string;
 Prop2:Number;
}  

@Component() 
export class MyComponent{
 @Input() myObject: MyObject;
 DoSomethingIfProp1Change(){
  console.log(myObject.Prop1);
 }
}

How can I detect if Prop1 was changed from Hostcomponent and then execute the DoSomethingIfProp1Change method from inside MyComponent?

如何检测 Prop1 是否已从 Hostcomponent 更改,然后从 MyComponent 内部执行 DoSomethingIfProp1Change 方法?

回答by Thierry Templier

In fact, by default Angular2 detects changes when object reference is updated not its content. But this default behavior can be changed by using the DoCheckinterface.

事实上,默认情况下,Angular2 会在对象引用而不是其内容更新时检测更改。但是这个默认行为可以通过使用DoCheck接口来改变。

In your case (detecting that a property was updated into the myObjectobject, you could use the following approach:

在您的情况下(检测到属性已更新到myObject对象中,您可以使用以下方法:

@Component({
  selector: 'my-component',
  (...)
}) 
export class MyComponent implements DoCheck {
  @Input() myObject: MyObject;
  differ: any;

  constructor(differs:  KeyValueDiffers) {
    this.differ = differs.find([]).create(null);
  }

  ngDoCheck() {
    var changes = this.differ.diff(this.myObject);

    if (changes) {
      changes.forEachChangedItem((elt) => {
        if (elt.key === 'prop1') {
          this.doSomethingIfProp1Change();
        }
      });
    }
  }

  doSomethingIfProp1Change() {
    console.log('doSomethingIfProp1Change');
  }
}

When the value of the prop1property is updated, the doSomethingIfProp1Changemethod is called.

prop1属性的值被更新时,该doSomethingIfProp1Change方法被调用。

See this plunkr: http://plnkr.co/edit/uvOKMXQa9Ik8EiIhb60Y?p=preview.

请参阅此 plunkr:http://plnkr.co/edit/uvOKMXQa9Ik8EiIhb60Y?p=preview 。

回答by Günter Z?chbauer

You can use observables to support notification of subscribers. Angular itself doesn't provide support for observing changes of internal object state.

您可以使用 observable 来支持订阅者的通知。Angular 本身不支持观察内部对象状态的变化。

class MyObject{
  constructor() {
    this.prop1Change$ = new Observable(observer => 
        this._prop1Observer = observer).share(); // share() allows multiple subscribers

    this.prop2Change$ = new Observable(observer =>
        this._prop2Observer = observer).share();
        console.debug(this._prop2Observer);
  }

  prop1Change$: Observable<string>;
  private _prop1Observer: Observer;
  _prop1:string;
  get prop1():string { return this._prop1 };
  set prop1(value:string) {
    this._prop1 = value;
    this._prop1Observer && this._prop1Observer.next(value);
  }

  prop1Change$: Observable<number>;
  private _prop2Observer: Observer;
  _prop2:Number;
  get prop2():number { return this._prop2 };
  set prop2(value:number) {
    this._prop2 = value;
    console.debug(this);
    this._prop2Observer && this._prop2Observer.next(value);
  }
}

This code could be shortened by using Subjectbut Observableshould be favored over Subject.

这段代码可以通过使用来缩短,SubjectObservable应该优先于Subject.

@Component() 
export class MyComponent{
  @Input() myObject: MyObject;

  count2:number;

  DoSomethingIfProp1Change(){
    console.log(myObject.prop1);
  }

  ngOnChanges(changes: {[propName: string]: SimpleChange}) {
    console.log('changes');
    if(changes['myObject']) {
      if(this.prop2Subscription) {
        this.prop2Subscription.unsubscribe();
      }
      this.prop2Subscription = this.myObject.prop2Change$.subscribe(value => {
        this.count2 = value;
        console.log('count2: ' + value);
      });
      // same for `prop2`
    }
  }
}

Plunker example

Plunker 示例

See also Delegation: EventEmitter or Observable in Angular2

另请参阅委托:Angular2 中的 EventEmitter 或 Observable