Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Typescript 检测组件输入的嵌套属性的更改_Typescript_Angular - Fatal编程技术网

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

Typescript 检测组件输入的嵌套属性的更改,typescript,angular,Typescript,Angular,以简化的方式,我有一个Angular2组件和一个输入对象,如下所示: class MyObject{ Prop1:string; Prop2:Number; } @Component() export class MyComponent{ @Input() myObject: MyObject; DoSomethingIfProp1Change(){ console.log(myObject.Prop1); } } 如何检测Prop1是否已从Hostcomponent中更

以简化的方式,我有一个Angular2组件和一个输入对象,如下所示:

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

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

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

您可以使用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);
  }
}


另请参见

事实上,默认情况下,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');
  }
}
更新
prop1
属性的值时,将调用
doSomethingIfProp1Change
方法


请参阅此plunkr:。

我更新了我的答案(修复了一些错误并添加了一个可用的Plunker示例)。嗨,gunter,在您提供的链接上,有一个关于使用主题的更新建议,您对最佳实践有何建议?@ThomasP1988不确定您的意思。
EventEmitter
用于
@Output()
s仅限。关于最佳实践还有什么不清楚的地方吗?在您提供的“委派:事件发射器或角度观察2”链接中,最佳答案建议使用行为主体而不是观察主体。您同意吗?这不取决于您的要求。
行为主体
主体
之间存在差异>.BehaviorSubject会立即向新订阅者发出上次发出的值。如果第一个事件是在订阅者订阅之前发出的,则此功能非常有用。使用
Subject
仅当发出另一个事件时才会收到通知,而
BehaviorSubject
会立即重放上次事件。
observeable
是一个更简单的方法
Subject
的ne版本。通常认为使用
Observable
而不是
Subject
是更好的做法,但是
Subject
的设置更容易一些。试图理解这实际上在做什么,但同时,我在构造函数中遇到了一个错误,create不需要任何参数。
@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');
  }
}