【问题标题】:Subscribe to event emitter when array is loaded加载数组时订阅事件发射器
【发布时间】:2016-11-11 13:01:59
【问题描述】:

我有以下代码:

this.itemsService.getItems()
    .subscribe(i => this.items = i);

但是,用户可以选择一种类型的项目,所以我有一个事件发射器:

this.typeofitems.selectedType.subscribe(type => this.type = type);

它运行良好。

现在我想用filter function 过滤this.items 的项目列表。问题是,我不知道项目的加载何时完成,尽管我在订阅中添加了日志:

this.itemsService.getItems()
    .subscribe(i => {this.items = i; console.log("completed");});

它表明我已经完成了。所以我尝试了:

this.itemsService.getItems()
    .subscribe(i => {
        this.items = i;
        this.typeofitems.selectedType.subscribe(type => {
            this.type = type;
            this.filterByType();
        });
    });

filterByType() {
    this.itemsfilteredByType = this.items.filter(i => i.type === this.type)
}

但它不起作用。所以我想我不能在下标内订阅。 我怎样才能实现它?

【问题讨论】:

    标签: angular typescript rxjs rxjs5


    【解决方案1】:

    请注意,您在 filter() 回调中使用的是 = 而不是 ==,因此请确保这不是问题所在。

    无论如何,您可以使用运算符combineLatest(),它会在其任何一个源发出一个值时发出一个值(而每个源中至少必须发出一个值):

    function getItems() {
      return Observable.of([{type: 1, val: 345}, {type: 2, val: 107}, {type: 1, val: 926}, {type: 2, val: 456} ]);
    }
    
    let typeOfItems = new Subject();
    
    Observable.combineLatest(getItems(), typeOfItems)
      .subscribe(vals => {
        let [items, typeOfItem] = vals;
    
        let results = items.filter(i => i.type == typeOfItem);
        console.log(results);
      });
    
    typeOfItems.next(2);
    

    这会按type == 2 过滤项目并打印到控制台:

    [[object Object] {
      type: 2,
      val: 107
    }, [object Object] {
      type: 2,
      val: 456
    }]
    

    这要归功于combineLatest(),它首先接收所有项目,然后我告诉它通过type == 2 使用typeOfItems.next(2); 过滤它们,这会触发对combineLatest() 的回调调用,它使用Array.filter() 来实际过滤和打印过滤后的项目(注意这是Array.fitler() 而不是Observable.filter())。

    观看现场演示:https://jsbin.com/nenosiy/5/edit?js,console

    顺便说一句,您当然可以在另一个 subscribe() 回调中使用 subscribe()。请记住,您必须手动取消订阅以前的订阅。

    看到一个非常相似的问题:Dynamically filtering rxjs stream

    【讨论】:

    • 问题是:当typeOfItems发生变化时,会不会再次调用getItems?
    • @FacundoGFlores 为什么不亲自尝试一下呢?只需在末尾添加typeOfItems.next(1); 看看会发生什么。
    猜你喜欢
    • 2016-04-22
    • 1970-01-01
    • 2022-01-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-04
    • 2017-04-06
    • 2020-08-01
    相关资源
    最近更新 更多