【问题标题】:Refreshing list using combineLatest: Angular2 + RxJS使用 combineLatest 刷新列表:Angular2 + RxJS
【发布时间】:2017-10-10 19:08:44
【问题描述】:

我有一个组件,我在其中显示从对 API 的 http 请求生成的数据(用户)表。表格上有多种过滤器,所以我生成表格数据如下:

this.displayUsers$ = Observable.combineLatest(
            this.users$,
            this.siteFilter$,
            this.clientFilter$,
            this.activeFilter$,
            this.nameFilter$
        )
            .map(([users, siteFilter, clientFilter, activeFilter, nameFilter]) => {
                console.log("Users changed? ", users);
                if (siteFilter === null
                    && clientFilter === null
                    && activeFilter === null
                    && nameFilter.length < 1) {
                    return users;
                }
                return users
                    .filter(user => {
                        // manipulate users array based on filters
                    })
            });

xFilter$s 是 BehaviorSubjects,它们发出新值以响应对其在模板中输入的更改。 users$ 分配如下:

this.users$ = this.userService.getList();

getList() 返回一个 http 请求以获取用户列表。

只要更改过滤器,列表就会成功更新,但是当我需要用新用户更新列表时会遇到问题。例如,用户可以对用户表执行 CRUD 操作(即删除用户)。但是,当用户被删除时,表不会更新以反映此更改。我目前用来(尝试)刷新表的方法是在删除操作的成功回调中调用刷新函数:

refreshUserList() {
        console.log("Refreshing user list");
        this.users$ = this.userService.getList();
    }

尽管在操作完成后调用了这个,combineLatest observable 不会再次被“触发”,并且列表数据仍然是陈旧的。有没有更好的方法用 http 请求刷新 combineLatest 生成的数据?

【问题讨论】:

    标签: javascript angular typescript rxjs combinelatest


    【解决方案1】:

    主要问题是在用户列表更新的情况下,您的 users$ observable 不会发出任何新值。你必须这样做。

    这是一个如何解决它的想法的骨架:

    const updateUsersTrigger = new Subject<void>();
    
    this.displayUsers$ = Observable.combineLatest(
        // switchMap() will re-subscribe to this.userService.getList() observable on each emit from updateUsersTrigger
        // thus making http requests each time when user list should be updated.
        updateUsersTrigger.startWith(null).switchMap(() => this.userService.getList()),
        this.siteFilter$,
        this.clientFilter$,
        this.activeFilter$,
        this.nameFilter$
    )
        .map(([users, siteFilter, clientFilter, activeFilter, nameFilter]) => {
    
        .......
    
    });
    
    // this will trigger user list update
    updateUsersTrigger.next();
    

    【讨论】:

    • 这很有意义,感谢您的建议。但是,我认为我的实现遗漏了一些东西,因为现在我没有得到任何表数据(即使我更改了过滤器)。我改变了 refreshUserList() { updateUsersTrigger.next();并在 ngOnInit() 中调用它,但仍然没有运气。
    • @natmegs,尝试这样的事情:updateUsersTrigger.startWith(null).switchMap(() =&gt; ... call service ...) 而不是在 ngOnInit() 中发出一些东西 - 我不希望它实际工作,我认为它触发得太早了。
    【解决方案2】:

    我还不能发表评论,所以如果我错了或者这是不可能的,我会在这里写信并纠正我。如果您在成功删除时使用.splice() 来更新DOM,而不是发送另一个http 请求,那不是更容易并且对客户端的压力更小吗?

    【讨论】:

    • 无论哪种方式,OP 都需要一些 observable 来发出新数组,无论是 http 请求还是 splice() 都会导致一些 Observable.map() 或其他东西。
    猜你喜欢
    • 2017-06-25
    • 2019-03-03
    • 2019-08-25
    • 2021-02-21
    • 2019-01-08
    • 1970-01-01
    • 2017-05-24
    • 1970-01-01
    • 2021-03-06
    相关资源
    最近更新 更多