Angular Observable订阅回退?

时间:2017-06-27 04:01:53

标签: javascript angular typescript rxjs

我使用的是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的方法,所以任何帮助都会受到赞赏。

谢谢!

1 个答案:

答案 0 :(得分:2)

Observables本身就是无国籍的。要跟踪值(或当前值),您需要使用SubjectBehaviorSubject

currentPlayerService中,创建一个名为BehaviorSubject的{​​{1}}:

playerBSubject

请注意,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只是为了跟踪&#34;当前&#34;如果您使用BehaviorSubject跟踪当前玩家,那么玩家的价值就完全不需要了。所有这些都可以归结为一个单一的服务。

currentPlayerService

如果你想获得当前值,你可以在控制器中执行:

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