我正在使用Angular 4,我有一个组件,它位于我的应用程序中的’player /:id’路径中.当玩家从应用程序内导航到此路线时,我使用currentPlayerService来同步应用程序中的当前玩家.这适用于以下代码.
this.currentPlayerService.getPlayer()
.subscribe((player) => this.currentPlayer = player);
但是,当应用程序直接加载到’player /:id’路径(来自外部链接)时,我可以注释掉上面的内容并使用下面的代码从路径参数设置currentPlayer.
this.route.params.subscribe(params => {
this.playerService.getPlayer(params.id)
.subscribe((player) => {
this.currentPlayer = player;
this.currentPlayerService.setPlayer(player);
});
});
我想做的事情(并且很难找到“反应函数编程”的说法)只有当this.currentPlayerService.getPlayer()在加载时没有值时才从params加载播放器.我很难想到在某种逻辑控制流程中使用Observable的方法,所以任何帮助都会受到赞赏.
谢谢!
解决方法:
可观测量本身是无国籍的.要跟踪值(或当前值),您需要使用Subject或BehaviorSubject.
在currentPlayerService中,创建一个名为playerBSubject的BehaviorSubject:
export class CurrentPlayerService{
public playerBSubject: BehaviorSubject<any>;//can be type of Player if you have such type
constructor(){
this.playerBSubject = new BehaviorSubject({})//any value that you want to initialize
}
getPlayer(){
//do your logic here, whatever that is.
//I am using an Observable.of to mimic a http request
Observable.of({})
.subscribe((player)=>{
this.playerBSubject.next(player)//this will update the subject with the latest value
});
return this.playerBSubject.asObservable();
}
}
请注意,.next()方法将更新主题的值,您可以使用.asObservable()将其作为可观察对象返回.
现在,在组件控制器中,您可以检查您的BehaviourSubject是否存在(或具有您想要的值),并且只在需要时调用playerService.getPlayer().
this.route.params.subscribe(params => {
//check if BehaviorSubject exist or not
if (this.currentPlayerService.playerBSubject.getValue() === {}) {
this.playerService.getPlayer(params.id)
.subscribe((player) => {
this.currentPlayer = player;
this.currentPlayerService.setPlayer(player);
});
}
});
建议:
我不确定为什么你需要两个服务,即currentPlayerService和playerService.如果您的currentPlayerService只是为了跟踪播放器的“当前”值,那么您根本不需要它,如果您使用BehaviorSubject来跟踪当前播放器.所有这些都可以归结成一个单一的服务.
export class PlayerService {
public playerBSubject: BehaviorSubject<any>;
constructor() {
this.playerBSubject = new BehaviorSubject({})
}
getPlayer(id) {
Observable.of({id}) // implement your own logic
.subscribe((player) => {
this.playerBSubject.next(player)
});
return this.playerBSubject.asObservable();
}
setPlayer(id) {
return Observable.of({id})//implement your own logic
.subscribe(newPlayer => this.playerBSubject.next(newPlayer))
}
}
在您的控制器中,如果您想获得当前值,您可以这样做:
this.currentPlayer = this.playerService.playerBSubject.getValue();
在asObservable的帮助下你可以这样做:
this.playerService
.asObservable()
.subscribe(player => {
if (player === {}) {
this.route.params.subscribe(params => {
this.playerService.getPlayer(params.id); //voila, your player is updated
})
}
//remember to update the value
this.currentPlayer = player
})