2017-01-19 4 views
1

私は、次の非正規化Firebaseの構造を有する:Angularfire2(活字体)とネスト観測

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

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

そして、私は私のコンポーネントでqualityが発注threads上場しています:

特色-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を認識しないことを警告します(明らかにそうではないため)。 af: Angularfire;というプロパティを宣言してコンストラクタの外側にthisを使用することができますが、コンソールエラーTypeError: Cannot read property 'database' of undefinedが発生します。これは、プロパティを宣言することがAngularFireサービスと同じではありません。私はこの質問に関連するにはあまりにも笑っているかもしれないいくつかの他の事を試しました。

私はここで何が起こっているか完全にはわかりません。この問題は、threadsからauthorの値をパラメータとして渡すことができるメソッドを作成することができなくなります。これは、コンストラクタ内でメソッドを定義することができず、コンストラクタafの外側がnullであるためです。

私はこのことが中核的な問題に対処していることさえ完全にはわかりません。私はmemberidへの直接的な経路の恩恵を受けているこの単純な場合だけでなく、いつでもこれらのオブザーバブルに参加/ネストすることができます。 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') 
} 

今のところ、memberのそれぞれに対してusernameプロパティが記録されますコンソール。残念ながら、私は鍵を得るだけです。値は空です:

enter image description here

...私にとっては奇妙なことですが、getUsername()がメンバーIDを問合せパスに正常に渡していることを考えればわかります。

enter image description here

これは、パスが正しいことを示して私のFirebaseコンソールビューからグラブです。

enter image description here

私は、これは、使用の質問ではなく技術の問題であるという事実を認識しています。

+1

あなたは、コンストラクタの外AFフィールドにアクセスする場合は、その前にプライベート追加します。 'private af:AngularFire'。今度はこれを行うことができます.af.someMethod – Steveadoo

答えて

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> 
+0

'do'プロパティが' FirebaseListObservable '型で終了しないという、typescript警告を受け取ります。 –

+1

その演算子をインポートする必要があります。 'rxjs/add/operators/do'と思います。 – Steveadoo

+0

私はあなたがそのメソッドをどのように定義するのか興味があります。 'this.threads'に' do'を付けるために、タイプをFirebaseListObservableからObservableに変更しなければなりませんでした。このメソッドは 'database'のメソッドではないので、それがどのようにアタッチされているのかわかりません。私は 'this.getUsername(thread.author);を実装しました。これらの調整の後、私のメソッドは' [object Object] 'としてレンダリングするオブジェクトを返します。 –