2017-08-06 29 views
3

所以我有兩個表。其中之一是我的用戶存儲塊 另一個存儲這些塊的數據。angularfire2 rxjs加入兩個表的動態更新的observables

我想這樣在我的組件我根據數據ID

- 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調用需要一些變化:

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; 
    }); 
    }); 

您對blocks.map調用返回觀測的數組,所以你要使用的combineLatest簽名是this one

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

你傳遞一個數組的可觀察性,並將結果稱爲您的項目功能。只需將它們收集到一個數組中,迭代你的blocks,並將結果賦給適當的索引。


如果您正在使用ngrxOnPush變化檢測,你應該確保突變不是塊陣列或塊本身作出。爲了避免突變,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

Cartant非常感謝。週末我放棄了對它的抨擊。因爲我的大腦很爛。 –

+0

@ShaneMoore,你可以upvote或接受答案,如果它幫助 –

+0

你是對的,這個是幾乎完全一樣[this one](https://stackoverflow.com/a/45529139/2545680) –