使用Angularfire2(TypeScript)嵌套Observable

时间:2017-01-19 17:10:58

标签: angular firebase firebase-realtime-database angularfire2

我有以下非规范化的Firebase结构:

members
  -memberid1
    -threads
       -threadid1: true,
       -threadid3: true
    -username: "Adam"
    ...

threads
  -threadid1
      -author: memberid3
      -quality: 67
      -participants
         -memberid2: true,
         -memberid3: true
      ...

我在我的组件中列出threads排序的quality

功能-threads.component.ts

constructor(af: AngularFire) {
    this.threads = af.database.list('/threads', {
        query: {
            orderByChild: 'quality',
            endAt: 10
    }
});

以下是我的观点摘录:

功能-threads.component.html

<div *ngFor="let thread of threads | async" class="thread-tile">
...
    {{thread.author}} //Renders memberid3
...
</div>

我不想在这里呈现memberid3,而是想获得相应成员的用户名属性值。

解决方案herehere都会在构造函数之外获取它们的可观察对象,而不是如Angularfire2 docs中所示。他们使用this.af.database。当我在构造函数中使用this关键字时,TypeScript警告它不会将af识别为组件属性(因为它显然不是)。我可以通过声明属性this在构造函数之外使用af: Angularfire;,但后来我得到控制台错误TypeError: Cannot read property 'database' of undefined,我认为这与声明属性isn'的事实有关。与注入AngularFire服务相同。我已经尝试过其他一些可能过于滑稽而且与这个问题无关的事情。

我不完全确定这里发生了什么。此问题阻止我创建一个方法,我可以将author的值threads作为参数传递给我。这是因为无法在构造函数中定义方法,并且构造函数af之外的方法为null。

我甚至不确定这是否解决了核心问题。我希望能够随时加入/嵌套这些可观察对象,而不仅仅是在这种更简单的情况下,当我获得memberid的直接路径时。关于嵌套observable的问题有很多问题,其解决方案不使用Angularfire 2.不幸的是,我无法将它们转换为Angularfire 2解决方案。

更新

我将组件中的所有逻辑移到了服务上,然后将服务的方法getFeaturedThreads()注入到组件中,其中包含以下内容:

ngOnInit() {
    this.threads = this.featuredThreadsService.getFeaturedThreads()
    this.threads.subscribe( 
        allThreads => 
            allThreads.forEach(thisThread => {
                this.featuredThreadsService.getUsername(thisThread.author)
                    .subscribe( 
                        username => console.log(username))
            })
    )
}

getUserName()看起来像这样:

getUsername(memberKey: string) {
    return this.af.database.object('/members/' + memberKey + '/username')
}

现在,这会将每个username的{​​{1}}属性记录到控制台。不幸的是,我只得到钥匙。值为空:

enter image description here

...这对我来说很奇怪,因为member成功地将成员ID传递到查询路径中。

enter image description here

这是来自我的Firebase控制台视图的抓取,显示路径正确。

enter image description here

我认识到这是一个使用问题而不是技术问题。

1 个答案:

答案 0 :(得分:1)

我会像这样实现它,我将它移动到ngOnInit,因为你真的不应该在构造函数中这样做。只需在构造函数中的af声明之前添加private。

public ngOnInit() {
    this.threads = this.af.database.list('/threads', {
        query: {
            orderByChild: 'quality',
            endAt: 10
        }
    }).do(threads => {
        threads.forEach(thread => {
            thread.author = this.af.database.getName(thread.author); //actual method to get the username
        });
    });
}

你的组件html

<div *ngFor="let thread of threads | async" class="thread-tile">
...
    {{thread.author | async}}
...
</div>