下面我在订阅后做了一个地图,但我想使用地图运算符。有人能指出我正确的方向吗?
getChildren(node: any) {
this.filter = {
codedName: node.id
};
this.eclassService.getEclassNodes(this.filter)
.subscribe(data => {
console.log("data", data);
data.map(child => {
this.children.push({
id: child.codedName,
name: `${child.codedName} ${child.preferredName}`,
hasChildren: true
});
});
});
// return this.asyncChildren.map((c) => Object.assign({}, c));
return this.children.map((c) => Object.assign({}, c));
}
答案 0 :(得分:1)
首先要做的事情是:你的函数不应该异步修改this.children并同时返回它。让我们来看看你的代码(Tobiah的回答有同样的错误)。
this.filter
值this.children
这是错误的,因为return不会等待异步调用完成。
顺便说一下:
Rx.Observable.from(this.eclassService.getEclassNodes(this.filter))
这是多余的。它就像Object.assign({})
,你正在使用它,也是多余的。
而且,你的问题解释不够。您是否需要将数据保存在this.children
中,或者您可以将其删除?
我建议将getChildren
函数设置为async,如下所示:
interface Node {
id: any;
name: string;
hasChildren: boolean;
}
getChildren(node: any): Observable<Node> {
// is it necessary to bind this to state? it is suspicious side effect
this.filter = {
codedName: node.id
};
return this.eclassService.getEclassNodes(this.filter)
.map((x: any[]) =>
x.map(child => ({
id: child.codedName,
name: `${child.codedName} ${child.preferredName}`,
hasChildren: true
}))
);
}
您需要了解的一个想法是, Observable.map会将您的函数应用于流中显示的每个对象。因此,如果您的流提供数组, Observable.map将在每个数组上应用函数,而不是在其元素上应用。所以你有类似(array) => doSmth(array)
的东西。如果需要修改数组中的对象,则函数doSmth
应该执行此操作。
现在您可以订阅您的功能或在async
管道的模板中使用它。
答案 1 :(得分:0)
Lukasz的回答对我有很大帮助,我设法解决它。
这是我完成的代码,考虑到Lukasz在答案中的提示。
我希望这可以帮助其他人,所以我附上完整的代码。
import { Component, OnInit } from "@angular/core";
import { ITreeOptions } from "angular-tree-component";
import { EclassService } from "../../services/eclass.service";
import "rxjs/add/operator/toPromise";
import "rxjs/add/operator/map";
@Component({
selector: "app-async",
template: `<tree-root #tree [options]="options" [nodes]="nodes"></tree-root>`,
styles: ["async-tree-example.component.css"]
})
export class AsyncTreeExampleComponent implements OnInit {
options: ITreeOptions = {
getChildren: this.getChildren.bind(this)
};
nodes = [];
children = [];
constructor(private eclassService: EclassService) {}
ngOnInit() {
const filter: any = { level: "1" };
this.eclassService.getEclassNodes(filter).subscribe(data => {
this.nodes = data.map(item => {
return {
id: item.codedName,
name: `${item.codedName} ${item.preferredName}`,
hasChildren: true
};
});
});
}
getChildren(node: any): Promise<object> {
const filter = {
codedName: node.id
};
return this.eclassService.getEclassNodes(filter)
.map((x: any[]) => {
return x.map(child => {
if (child.level === "4") {
return ({
id: child.codedName,
name: `${child.codedName} ${child.preferredName}`,
hasChildren: false
});
} else {
return ({
id: child.codedName,
name: `${child.codedName} ${child.preferredName}`,
hasChildren: true
});
}
});
})
.toPromise();
}
}
答案 2 :(得分:-1)
在查看documentation后,这似乎有效。
1)使用from
2)map
到该源迭代,返回任何你想要的变异。
3)subscribe
到该映射。
getChildren(node: any) {
this.filter = {
codedName: node.id
};
const source = Rx.Observable.from(this.eclassService.getEclassNodes(this.filter));
const children = source.map(child => ({
id: child.codedName,
name: `${child.codedName} ${child.preferredName}`,
hasChildren: true
});
children.subscribe((child) => {
this.children.push(child);
});
return this.children.map((c) => Object.assign({}, c));
}