【问题标题】:ngrx: how to combine observables for use in async pipengrx:如何组合可观察对象以在异步管道中使用
【发布时间】:2017-04-16 17:19:00
【问题描述】:

我正在尝试使用 observables 和 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 存储中获取 observable。

我遇到的问题是,当我的搜索框打开时,起初一切都是空的。只有在更新一个值之后,所有内容才会被填充。如果我直接将它与 store.let 绑定它就可以了。

我像这样在我的 HTML 中使用异步管道

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

但它在 *ngIf 中,所以只有在搜索框打开后才会被评估。 我猜异步管道在所有操作发生之后订阅并且没有新事件它没有获得值。但是为什么它与 store.let 一起工作呢?一个不同的 observable 总是给你一个价值?

问题是我做错了什么,我觉得我仍然缺少一些东西......额外的问题:这是一个很好的方法来处理可以中止或提交的数据卷影副本吗?

【问题讨论】:

  • 我不会保留另一个变量 this.filterChanges 只是为了保留订阅者的最新值。有运营商以更好的方式实现updateSetting。我建议你把它带到代码审查中。
  • 进一步认为我将所有这些逻辑都移到了我的 ngrx 减速器中,因为我需要在其他地方访问卷影副本,所以我认为它更适合我......但这是对整个可观察的东西的一个很好的教训。
  • 这也是个好办法

标签: angular typescript rxjs ngrx


【解决方案1】:

使用rxjs/BehaviorSubject 而不是普通的rxjs/Subject。它会将收到的最后一个项目提供给新订阅者。

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

之后不需要next(),因为它在构造函数上取值。 Observable.combineLatest() 届时应该可以正常工作。

【讨论】:

    猜你喜欢
    • 2018-09-20
    • 2018-07-24
    • 1970-01-01
    • 1970-01-01
    • 2019-10-31
    • 1970-01-01
    • 1970-01-01
    • 2018-02-16
    • 2019-06-27
    相关资源
    最近更新 更多