为BehaviorSubject设置新值后,Observable不会发出相应的值

时间:2019-07-14 18:45:42

标签: angular typescript rxjs

我已按照这种方法https://stackblitz.com/edit/facades-with-rxjs-only?file=src%2Fapp%2Fuser.facade.ts在NG应用中通过服务来组织状态管理。我遇到state$可观察到的问题,该问题仅将initialExpensesState的值传递给BehaviorSubject并发出一次,而addExpensesGroup方法按预期为BehaviorSubject状态设置了新值,但没有从state$以及expenseGroups$和其他派生的Observable发出的值:

@Injectable()
export class ExpensesService {
  projectId$;

  private store = new BehaviorSubject<ExpensesState>(initialExpensesState);
  private state$ = this.store.asObservable().pipe(
    tap(r => console.log('emitted value', r)), // => emits only once with initial value initialExpensesState
    distinctUntilChanged()
  );

  get expensesState(): ExpensesState {
    return this.store.getValue();
  }

  set expensesState(val: ExpensesState) {
    this.store.next(val);
  }

  expenseGroups$ = this.state$.pipe(map(state => state.expenseGroups),
    tap(r => console.log('expenseGroups$', r)), // emits only once with initial value initialExpensesState
    distinctUntilChanged());

  errorMessage$ = this.state$.pipe(map(state => state.errorMessage), 
   tap(r => console.log(' errorMessage$', r)), // emits only once 
   distinctUntilChanged())

  isLoading$ = this.state$.pipe(map(state => state.isLoading));

  vm$: Observable<ExpensesState> = Observable.combineLatest(this.expenseGroups$, this.errorMessage$, this.isLoading$).pipe(
    map(([expenseGroups, errorMessage, isLoading]) => ({ expenseGroups, errorMessage, isLoading }))
  );


  constructor(
    private http: HttpClient,
    private appService: AppService,
    private route: ActivatedRoute
  ) {

    this.projectId$ = this.route.params.pipe(
      map(({ id }) => id), 
      tap(r => console.log('response1', r)));

    Observable.combineLatest(this.projectId$, this.expenseGroups$).pipe(
      tap(r => console.log('response', r)), // emits only once
      switchMap(([projectId]) => this._getExpenseGroups(projectId))
    ).subscribe(expenseGroups => {
      this.expensesState = { ...this.expensesState, expenseGroups, isLoading: false}
      })
    }

 addExpensesGroup() {
  return this.http
    .get(this.appService.getBaseUrl()+'/api/template/group')
    .subscribe(response => {
      const group = {
        models: response['models'],
        isNew: true
      };

    this.expensesState = {
      ...this.expensesState,
      expenseGroups: [group, ...this.expensesState.expenseGroups],
    }) // set new value for `BehaviorSubject` as expected 

    console.log('expensesState',this.expensesState) // new state set but state$ did not trigger with new value 
  })
}

_getExpenseGroups(projectId): Observable<any> {
   return this.http.get(this.appService.getBaseUrl() + `/api/expenses/groups/${projectId}`)
}

0 个答案:

没有答案