首页 文章

将Observable <any>转换为Observable <any []>

提问于
浏览
1

我使用firebase实时数据库在ionic3应用程序上工作 . 因此我使用angularfire2 . 该应用程序允许用户存储链接 . 链接由网址和相关标签组成 . 这就是我的数据库结构的样子:

firebase database structure

所有链接均位于 /links/ . 对于用户,链接存储为引用键,位于 /users/this.user/links/ .

在视图中,我想列出某个用户的所有链接 . Template detail:

<ion-item *ngFor="let item of items | async">
      <h3>{{item.url}}</h3>
      <!-- TODO: add tags and other meta information -->
    </ion-item>

这是组件构造函数中发生的事情:

this.items = this.db.list('/users/' + this.user + '/links/')
    .flatMap(x => x)
    .flatMap(x => {
        let y: any = x;
        return this.db.list('/links/' + y.$key);
    })
    .map(res => {
        let url: string;
        let tags: string[] = [];

        for (let r of res) {

                // filter out tags
                if (r.$key === 'tags') {
                    for (let key in r)
                        if (key) tags.push(key);
                }

                // filter out url
                if (r.$key === 'url') {
                    for (let key in r) {
                        url = r[key];
                        break;
                    }
                }
            }
        } // for (let r of res)

        let link: Link = new Link(url, tags);
        return link;
    });

this.items.subscribe(res => {
    console.log(res);
});

这样我的最终observable就会发出用户链接对象 . 组件订阅中的 console.log(res) 显示了所需的结果:

component subscription console log

但是因为我发出了Link对象,Angular告诉我ngFor只支持iterables:

enter image description here

最后,我的问题是:

  • 如何将 items observable转换为模板中ngFor可迭代的东西?

  • 有没有更好的方法来使用rxjs运算符来进行我想要的过滤?

非常感谢提前!

1 回答

  • 0

    这就是你需要在Rx中完成它的方法 . 我假设你想要摆脱响应中的所有数据,只获取标签和网址

    const linkFromRaw = linkList => linkList
        .map(linkResponse => new Link(linkResponse.url, linkResponse.tags);
    
    const linkToDetail = link => this.db.list('/links/' + link.$key))
    
    this.items = this.db.list('/users/' + this.user + '/links/')
      .flatMap( links => Observable.forkJoin(links.map(linkToDetail))
         .reduce(
           (finalResponse, linkResponseArr) =>[...finalResponse, ...linkResponseArr],
           []
         )
      )
      .map(links => links.map(linkFromRaw));
    

相关问题