我需要在angular 2项目中使用REST API上传一个n-ary树。 我有一项服务允许我添加如下节点:
addNode(node: TreeNode, parentId: number): Observable<NodeJson>
TreeNode是一个对象:
{
data: any,
children: TreeNode[]
}
我需要父节点的id能够添加子节点,并且这个id在NodeJson对象中。
我目前的解决方案是:
uploadTreeNode(node: TreeNode, parentId: number) {
this.node_service.addNode(node, parentId)
.subscribe(uploaded_node => {
for (let child of node.children) {
this.uploadTreeNode(child, uploaded_node.id)
}
}
}
哪个工作正常,但这是我的问题:我需要知道整棵树的时间 已上传,这种方法无法实现,因为我在每次通话时直接订阅了observable,我无法知道它何时完成。
实际上,我正在努力实现这一功能:
uploadNodeTree(node: TreeNode, parentId: number): Observable<NodeJson>
一旦从儿童上传中的所有Observable完成后,会返回一个Observable。
有没有办法用Rxjs运算符做这样的事情?
答案 0 :(得分:2)
正如所指出的那样,expand
是正确的运营商。解决方案是上传第一个节点并使用expand
创建来自其子节点的请求流并将其“附加”到源流,一旦没有更多子节点,只需发送empty()以结束流:
uploadTreeNode(node: TreeNode): Observabe<NodeJson> {
return this.node_service.addNode(node, rootId)
.map(uploaded_node => ({id: uploaded_node.id, current_node: node})
.expand({id, current_node} => {
if (current_node && current_node.children) {
let reqs = current_node.children.map(n => this.nodeService.addNode(id, n))
return Observable.merge(...reqs)
} else {
return Observable.empty()
}
})
}
现在我能做到:
this.uploadTreeNode(myNode, 1).subscribe(uploaded_node => {
console.log('Node has been uploaded: ' + uploaded_node),
})
感谢大家的帮助。