2017-08-06 7 views
3

したがって、私は2つのテーブルを持っています。そのうちの1つはブロックを格納するユーザーです もう1つはこれらのブロックのデータを格納します。angularfire2 rxjsは動的更新で2つのテーブルからobservablesを結合します

私は自分のデータとブロックのリストを取得し、私のコンポーネント内のように、次のコードでDATAID

- user 
    - blocks 
     - block1 
      - blockSize 
      - blockOptions 
       - dataID 
     - ... 

- data 
    - dataId1 
     - stuff ... 
    - ... 

に従って正しくこれらを結合しようとしています、私は私のブロックとデータを取得しますが、データのノードがまだありますFirebaseObervableです。だから私は私のダムコンポーネントで非同期を使用する必要があります。私が求めているのは、これらを正しく組み合わせて非同期パイプを使用し、データをサブコンポーネントにプッシュするだけなのです。動的な変更を失うことはありません。

return this.db.list(`/user/${this.userId}/blocks`).switchMap((blocks:Block[]) => { 
    let blockData$ = blocks.map(block => {   
     return this.db.object(`/data/${block.blockOptions.dataID}`) 
    }); 
    return Observable.combineLatest(blockData$,blocks, (bData,block) => { 
    block.data = bData; 
    return blocks; 
    }); 
}) 

テンプレートの例私は本当に正しい方向に任意のナッジを閉じ感じる事前に

//what I want to happen 
*ngFor="let block of blocks | async"> 
<dumb-component [blockData] = "block.data"></dumb-component> 

//what I have to do now 
*ngFor="let block of blocks | async"> 
<dumb-component [blockData] = "block.data | async"></dumb-component> 

おかげで

答えて

2

をいただければ幸いあなたは近くにあります。これは、いくつかの変更を必要とするだけObservable.combineLatestコールです:あなたが使用したいcombineLatest署名がthis oneあるのでblocks.map

return this.db.list(`/user/${this.userId}/blocks`) 
    .switchMap((blocks: Block[]) => { 
    let arrayOf$ = blocks.map(block => { 
     return this.db.object(`/data/${block.blockOptions.dataID}`) 
    }); 
    return Observable.combineLatest(arrayOf$, (...arrayOfData) => { 
     blocks.forEach((block, index) => { 
     block.data = arrayOfData[index]; 
     }); 
     return blocks; 
    }); 
    }); 

あなたの呼び出しは、観測の配列を返します。

export function combineLatest<T, R>(
    array: ObservableInput<T>[], 
    project: (...values: Array<T>) => R, 
    scheduler?: IScheduler 
): Observable<R>; 

あなたはそれに配列を渡しますオブザーバブルの関数を呼び出し、その結果を使ってプロジェクト関数を呼び出します。配列に集めてblocksを繰り返し、結果を適切なインデックスに割り当てます。


あなたがngrxまたはOnPush変化検出を使用している場合は、突然変異は、ブロック配列またはブロック自分自身に行われていないことを確認する必要があります。突然変異を避けるために、combineLatestコールは次のようになります。

return Observable.combineLatest(arrayOf$, (...arrayOfData) => { 
    return blocks.map((block, index) => { 
    const data = arrayOfData[index]; 
    if (block.data !== data) { 
     // If the block has no data or if the data has changed, 
     // copy the block to avoid mutating it. 
     return Object.assign({}, block, { data }); 
    } 
    return block; 
    } 
}); 
+0

カートゥントありがとうございました。私は週末にそれを叩きつけた。私の脳は濃いので。 –

+0

@ShaneMoore、あなたがアップルボートするか、答えが –

+0

の場合、これは[this one](https://stackoverflow.com/a/45529139/2545680)とほぼ同じです –

関連する問題