简体   繁体   中英

Angular 2+ detect object property change inside service

Let's say we have a service like this one:

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;
  }

}

Is there some way to detect supermanPropertyUpdated without using the updateSupermanProperty() function but by eg setting this.superman.power = 10 ?

I found some posts that suggest the KeyValueDiffer in combination with the DoCheck hook, but that is not available for services.

You can use get/set methods.

In your example:

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;
  }

}

After this you can use:

SupermanService.power = 10;

and all the listeners will be notified

Update

Another implementation to solve this problem is modifying your Hero class adding a public EventEmitter property and subscribing to this from your service. Assign a setter for each property on your Hero class and emit the change like Output and in your service you can emit the changes.

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;
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM