2017-08-06 57 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) –