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

Xav*_*ver 5 typescript angular

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

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

@Component() 
export class MyComponent{
 @Input() myObject: MyObject;
 DoSomethingIfProp1Change(){
  console.log(myObject.Prop1);
 }
}
Run Code Online (Sandbox Code Playgroud)

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

Thi*_*ier 5

实际上,默认情况下,Angular2会在更新对象引用而不是其内容时检测更改.但是可以使用该DoCheck界面更改此默认行为.

在您的情况下(检测到属性已更新到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');
  }
}
Run Code Online (Sandbox Code Playgroud)

prop1更新属性的值时,将doSomethingIfProp1Change调用该方法.

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


Gün*_*uer 4

您可以使用可观察量来支持订阅者的通知。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);
  }
}
Run Code Online (Sandbox Code Playgroud)

该代码可以通过使用来缩短Subject,但Observable应该优于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`
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

笨蛋的例子

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

  • 这取决于您的要求。“BehaviorSubject”和“Subject”之间是有区别的。BehaviourSubject 立即向新订阅者发出最后发出的值。如果第一个事件在订阅者订阅之前发出,这非常有用。使用“Subject”,您只会在发出另一个事件时收到通知,而“BehaviorSubject”会立即重播最后一个事件。“Observable”是“Subject”的更简单的版本。通常认为使用“Observable”而不是“Subject”是更好的做法,但“Subject”更容易设置。 (2认同)