Angular 2+检测服务内部的对象属性更改

时间:2019-01-15 12:46:45

标签: javascript typescript angular6 angular-services key-value-observing

假设我们有这样的服务:

SupermanService {
  private _superman: Hero;
  public supermanReplaced = new EventEmitter<Hero>();
  public supermanPropertyUpdated = new EventEmitter<Hero>();

  public get superman(): Hero {
    return this._superman;
  }

  public set superman(superman): void {
    this._superman = superman;
    this.supermanReplaced.emit(superman);
  }

  public updateSupermanProperty(key: string, val: string | number): Hero {
    this._superman[key] = val;
    this.supermanPropertyUpdated.emit(superman);
    return this._superman;
  }

}

有没有某种方法可以检测supermanPropertyUpdated而不使用updateSupermanProperty()函数,而是通过例如设置this.superman.power = 10

我发现一些帖子建议将KeyValueDifferDoCheck挂钩结合使用,但不适用于服务。

1 个答案:

答案 0 :(得分:1)

您可以使用获取/设置方法。

在您的示例中:

class SupermanService {
  private _superman: Hero;
  public supermanReplaced = new EventEmitter<Hero>();
  public supermanPropertyUpdated = new EventEmitter<Hero>();

  public set power(level: integer) {
    this._superman.power = level;
    this._supermanPropertyUpdated.emit(this._superman);
  }

  public get superman(): Hero {
    return this._superman;
  }

  public set superman(superman: Hero): void {
    this._superman = superman;
    this.supermanReplaced.emit(superman);
  }

  public updateSupermanProperty(key: string, val: string | number): Hero {
    this._superman[key] = val;
    this._supermanPropertyUpdated.emit(superman);
    return this._superman;
  }

}

在此之后,您可以使用:

SupermanService.power = 10;

所有听众都会收到通知

更新

解决此问题的另一种实现方法是修改您的 Hero 类,添加一个公共的 EventEmitter属性,然后从您的服务中订阅该属性。为您的 Hero 类中的每个属性分配一个设置器,并发出 Output 之类的更改,并且在您的服务中可以发出更改。

class Hero {

    public onPropertyChange = new EventEmitter<Hero>();
    private _name: string;

    get name(): string {
        return this._name;
    }

    set name(value: string) {
        this._name = value;
        this.onPropertyChange.emit(this);
    }
}

class SupermanService {
  private _superman: Hero;
  public supermanReplaced = new EventEmitter<Hero>();

  public get superman(): Hero {
    return this._superman;
  }

  public set superman(superman: Hero): void {
    this._superman = superman;
    this.supermanReplaced.emit(superman);
  }

  public get supermanPropertyUpdated(): EventEmitter<Hero> {
    return this._superman.onPropertyChange;
  }
}