我是RxJS的新手。我想创建一个AppState
对象的可观察对象,可以随时更改,并订阅它以获得这些更改。这是一个精简的实现:
export class AppState {
public get observable(): Observable<any> {
return Observable.of(this._state);
}
}
// appState is injected into my component via angular DI
this.appState.observable
.subscribe((appState) => {
console.log('appState: ', appState);)
}, (err) => {
console.log('Error: ' + err);
}, () =>{
console.log('Completed');
});
但它只运行一次并立即调用completed
。因此,当我更改appState时,订阅已经结束。
如何让订阅永远保持活力,例如KnockOutJS风格。这用于Angular应用程序
更新:我部分使用Subject
。但问题是现在它发出了许多相同价值的副本。
// full appState.ts
import { Injectable } from '@angular/core';
import { Observable, Subject, BehaviorSubject } from 'rxjs';
export type InternalStateType = {
[key: string]: any
};
@Injectable()
export class AppState {
public _state: InternalStateType = {};
public subject: Subject<any>;
constructor() {
this.subject = new Subject();
}
/**
* Return an observable for subscribing to.
*/
public get observable() {
return this.subject;
}
/**
* Return a clone of the current state.
*/
public get state() {
this._state = this._clone(this._state);
this.subject.next(this._state);
return this._state;
}
/**
* Never allow mutation
*/
public set state(value) {
throw new Error('do not mutate the `.state` directly');
}
public get(prop?: any) {
/**
* Use our state getter for the clone.
*/
const state = this.state;
return state.hasOwnProperty(prop) ? state[prop] : state;
}
public set(prop: string, value: any) {
/**
* Internally mutate our state.
*/
return this._state[prop] = value;
}
private _clone(object: InternalStateType) {
/**
* Simple object clone.
*/
return JSON.parse(JSON.stringify(object));
}
}
需要更改哪些内容才能让每次更改只发出一次更改this._state
?
答案 0 :(得分:0)
您需要使用Subject或BehaviorSubject。
主题将在订阅者传递给Subject时向其发出值,而BehaviorSubject将在订阅时发出最后一个值,然后在值可用时继续发出值。