我理解如何使用BehaviorSubject
等简单类型,例如int string bool
等。但我刚尝试为类实例实现BehaviorSubject
,我非常确定我的做法是错误的......
这就是我现在所拥有的(顺便说一下):
//user.model.ts
export class User {
public accesstoken: string;
public details: UserDetails;
public subscriptions: Channel[];
private loaded: boolean;
}
//user.service.ts
export class UserService {
public activeUser: BehaviorSubject<User>;
...
// called when we want to update the users details
public updateUserDetailsFromServer(){
...
// set the instance to the new data.
this.activeUser.getValue().details = data.details;
// now update the BehaviorSubject (this feels so wrong)
this.activeUser.next(this.activeUser.getValue());
...
}
}
我确信有更清晰的方法来实现这一点。
答案 0 :(得分:1)
为了简化问题,我没有创建User
类。但是用你的实现替换对象应该很容易。
const { Observable, Subject } = Rx;
const input$ = new Subject();
const user = {
token: null,
loaded: false,
details: {}
};
const user$ = input$
.startWith(Object.create(user))
.scan((activeUser, { details }) => {
Object.assign(activeUser.details, details);
return activeUser;
})
.subscribe(x => console.log(x));
input$.next({ details: { name: 'Bob' } });
input$.next({ details: { role: 'Admin' } });
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
编辑:由于使用class
是您问题的一部分:
const { Observable, Subject } = Rx;
const input$ = new Subject();
class User {
constructor() {
this.token = null;
this.loaded = false;
this.details = {};
}
}
const user$ = input$
.startWith(new User())
.scan((activeUser, { details }) => {
Object.assign(activeUser.details, details);
return activeUser;
})
.subscribe(x => console.log(x));
input$.next({ details: { name: 'Bob' } });
input$.next({ details: { role: 'Admin' } });
<script src="https://unpkg.com/rxjs/bundles/Rx.min.js"></script>
我不建议你使用像这样的Observables。特别是,使用BehaviorSubject
,然后使用getValue()
从中提取数据。如上所示,我建议使用scan
来保存用户的当前值。
在您的情况下,input$
可以是一个或多个(合并的)流,可以更新活动用户(例如您的http
流)。这样,任何有兴趣更新为活跃用户的内容都可以subscribe
到user$
。