我有一个有属性的类,如何让这个类成为可观察的类,以监听属性的变化?
export class Model {
public id: number;
public name: string;
}
如何让这个类成为可观察的类,以监听属性的变化。
我需要这样的东西。
let m = new Model();
m.id = 10;
侦听变化。
m.pipe(map() => m.id);
我的方法是在构造函数中注入功能。我会避免在你的类里面声明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。
你可以为你的类属性添加getter和setter,在类内添加发射器,然后在类外添加监听器,监听该发射器的发射。
下面是一个简单的例子。
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);
}
}
let m = new Model();
m.id = 10;
const model$ = of(m);
model$.pipe(map()=> m.id);