2016-12-01 4 views
2

Я пытаюсь иметь теневую копию в ожидании изменения с помощью наблюдаемых и ngrx, и я бег в маленькую проблему, я не понимаю:ngrx: как совместить наблюдаемые для использования в асинхронной трубе

export class SearchBoxContainerComponent { 
    filterSettings$: Observable<FilterSettings>; 
    filterChanges: {[key:string]: any}; 
    filterChanges$: Subject<{[key:string]: any}>; 
    constructor(private store: Store<fromRoot.State>) { 
     this.filterChanges = {}; 
     this.filterChanges$ = new Subject(); 
     this.filterSettings$ = Observable.combineLatest(
      store.let(fromRoot.getFilterSettings), 
      this.filterChanges$, 
      (filterSettings, filterChanges) => { 
       return Object.assign({}, filterSettings, filterChanges); 
      } 
     ); 
     this.filterChanges$.subscribe(foo => { 
      console.log('filterChanges$: ', foo); 
     }); 
     this.filterSettings$.subscribe(foo => { 
      console.log('filterSettings$: ', foo); 
     }); 
     this.filterChanges$.next(this.filterChanges); 
    } 

    updateSetting(key, value) { 
     this.filterChanges = Object.assign({}, this.filterChanges, {[key]: value}); 
     this.filterChanges$.next(this.filterChanges); 
    } 

    submitSearchbox() { 
     // TODO send ngrx action to really update the filterSettings 
    } 
} 

Здесь я использую Observable.combineLatest вместо непосредственного использования

this.filterSettings$ = store.let(fromRoot.getFilterSettings); 

получить наблюдаемую от ngrx магазина.

Проблема, которая возникает у меня, заключается в том, что при первом открытии окна поиска все равно null. Только после обновления значения все заселяется. Если я напрямую свяжу его с store.let, он работает.

Я использую асинхронной трубку в моем HTML, как этот

<my-component [filterSettings]="filterSettings$ | async"></my-component> 

Но в * ngIf так только получить оценку после открытия SearchBox. Мое предположение, что асинхронная трубка подписывается после того, как все действие произошло, и без новых событий оно не получает значения. Но почему это работает с store.let? Это, что различное наблюдение, которое всегда дает вам ценность?

Вопрос в том, что я делаю неправильно, у меня создается впечатление, что у меня все еще не хватает чего-то ... бонусный вопрос: Это хороший способ сделать теневые копии данных, которые могут быть прерваны или отправлены?

+0

Я бы не оставил другую переменную 'this.filterChanges', чтобы сохранить последнее значение у подписчика. Есть операторы, чтобы реализовать 'updateSetting' лучше. Я предлагаю вам взять это в Code Review. –

+0

еще раз подумал, что я переместил всю эту логику в моем редукторе ngrx, где он лучше подходит, я думаю, потому что мне нужно получить теневую копию в другом месте ... но это был хороший урок для всего этого наблюдаемого материала. – arturh

+0

это тоже хороший способ –

ответ

4

Использовать rxjs/BehaviorSubject вместо простой rxjs/Subject. Он будет передавать последний элемент новым подписчикам.

this.filterChanges = {}; 
this.filterChanges$ = new BehaviorSubject(this.filterChanges); 

Вам не нужно next() после, так как он принимает значение по конструктору. Observable.combineLatest() должен работать как ожидалось к тому времени.

+0

, который отлично поработал, спасибо – arturh

 Смежные вопросы

  • Нет связанных вопросов^_^