如何使类变得可观察?

问题描述 投票:0回答:2

我有一个有属性的类,如何让这个类成为可观察的类,以监听属性的变化?

export class Model {
   public id: number;
   public name: string;
}

如何让这个类成为可观察的类,以监听属性的变化。

我需要这样的东西。

let m = new Model();
m.id = 10;

侦听变化。

m.pipe(map() => m.id);
angular angular8
2个回答
1
投票

我的方法是在构造函数中注入功能。我会避免在你的类里面声明subject,因为它们会很难自动整理。

你可以注入主题,但一个更简单的选择是注入一个回调。

在下面的测试类中,我允许为每个属性注入一个回调。如果值发生了变化,相关的回调就会在属性设置器中被调用。

export class MyClass {
  private _id: number;  
  private _name: string;

  constructor(private callback?: {
    id?: () => void,
    name?: () => void
  }) {}

  get id(): number { 
    return this._id;
  }

  set id(value: number) {
    if (value === this._id) {
      return;
    }

    this._id = value;

    if (this.callback && this.callback.id) {
      this.callback.id();
    }
  }

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

  set name(value: string) {
    if (value === this._name) {
      return;
    }

    this._name = value;

    if (this.callback && this.callback.name) {
      this.callback.name();
    }
  }
}

然后,从其他地方使用这个是相当简单的。

myClass: MyClass = new MyClass({
  id: () => this.onIdChange()
});

ngOnInit() {
  this.myClass.id = 10;   
  this.myClass.name = 'Default' 
}

private onIdChange() {
  console.log(`id changed to ${this.myClass.id}`);
}

如果你真的想改变这一点,使用subject也很简单。然后,调用代码将负责在适当的时候整理subjects。

DEMO: https:/stackblitz.comeditangular-ivy-hgxkc3


1
投票

你可以为你的类属性添加getter和setter,在类内添加发射器,然后在类外添加监听器,监听该发射器的发射。


1
投票

下面是一个简单的例子。

https:/stackblitz.comeditangular-ivy-kc9e4q。

import { Component, OnInit, VERSION } from '@angular/core';
import {BehaviorSubject} from 'rxjs';


@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent implements OnInit {
model: Model;

  ngOnInit() {
    this.model.id$.subscribe(newid => {
      // do something.
    });
  }
}
export class Model {
  // @ts-ignore
  private readonly _id = new BehaviorSubject<number>();
  readonly id$ = this._id.asObservable();
  // @ts-ignore
  private readonly _name = new BehaviorSubject<string>();
  readonly name$ = this._name.asObservable();

  get id(): number {
    return this._id.getValue();
  }

  set id(val) {
    this._id.next(val);
  }

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

  set name(val) {
    this._name.next(val);
  }
}

0
投票
let m = new Model();
m.id = 10;


const model$ = of(m);
model$.pipe(map()=> m.id);
© www.soinside.com 2019 - 2024. All rights reserved.