具有类实例的BehaviorSubject

时间:2017-06-08 04:50:53

标签: angular typescript rxjs

我理解如何使用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());
        ...
    }
}

我确信有更清晰的方法来实现这一点。

1 个答案:

答案 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流)。这样,任何有兴趣更新为活跃用户的内容都可以subscribeuser$