我有一个类,在初始化时从服务中检索数据并填充其中一个属性,即一个数组。这个类有一个函数可以对这个数组进行排序,过滤和返回。 当我实例化这个类的对象并调用这个函数时,我意识到它在构造函数和ngOnInit()函数完成之前被调用(可能是因为我使用来自Observables的异步内容,服务返回)。在外部调用我的类的任何函数之前,如何保证构造函数和init已完全执行?
export class BaseChoice implements PickAppraiser, OnInit {
weight = 0;
options = new Array<PickQuality>();
constructor(private championService: ChampionService) {}
ngOnInit() {
// Iterates through the list of champions adding them to the current object
this.championService.getChampions()
.subscribe(champions => {
// Iterates through the list of champions adding them to the current object
Object.keys(champions).map(key => this.options.push(new PickQuality(champions[key], 0)))
})
}
choose(n?: number): PickQuality[] {
var sorted = this.options.sort((a, b) => a.score - b.score);
return sorted;
}
}
我也尝试过像
这样的事情 choose(n?: number): PickQuality[] {
// Iterates through the list of champions adding them to the current object
this.championService.getChampions()
.subscribe(champions => {
// Iterates through the list of champions adding them to the current object
Object.keys(champions).map(key => this.options.push(new PickQuality(champions[key], 0)))
this.reevaluate(this.options);
var sorted = this.options.sort((a, b) => a.score - b.score);
var chosen;
if(n) chosen = sorted.slice(1, n);
else chosen = sorted.slice(1, 2);
return chosen;
});
}
我在choose()方法本身内运行异步请求,但它不允许我这样做,我假设因为返回变量不能保证存在。
答案 0 :(得分:1)
我认为,你应该看看你是如何从根本上布置你的组件的。您可以利用observables的方式将它们用作角度支持模板中的异步管道。
我不确定您的组件的详细信息,但我会做这样的事情:
export class BaseChoice implements PickAppraiser, OnInit {
weight = 0;
options$: Observable<PickQuality>;
champions$ : Observable<Champion>;
constructor(private championService: ChampionService) {}
ngOnInit() {
this.champions$ = this
.championService.getChampions();
this.options$ = this.champions$.map((champion, index) => {
return new PickQuality(champion, 0)))
})
}
}
在您的模板中,如果您执行*ngFor="let option in options$ | async)
,它会自动运行该流并为您提供结果,然后在您的choose()
函数中,我假设这是用户所采取的操作点击一下,你可以直接通过选项来做一些事情。
如果它比这更复杂,您可以将其映射到点击流,例如championClicked$
,并将这些点击映射到选项流中的正确选项。
要记住的是,您需要使用一系列操作设置这些observable,并且该管道每个Observer(订阅者)运行一次,这意味着每次使用| async
管道它订阅并运行整个事情。
花一些时间了解RxJS将为你的Angular 2开发带来巨大回报。
答案 1 :(得分:0)
由于您正在将options
属性初始化为空数组options = new Array<PickQuality>();
,为什么不检查choose方法呢?
choose(n?: number): PickQuality[] {
if (this.options && this.options.length !== 0) {
var sorted = this.options.sort((a, b) => a.score - b.score);
return sorted;
} else {
/* do something else if options is empty */
}
}
---编辑---
这是我在评论中提到的粗略版本:
export class BaseChoice implements PickAppraiser, OnInit {
weight = 0;
options = new Subject<PickQuality[]>();
constructor(private championService: ChampionService) {}
ngOnInit() {
this.championService.getChampions()
.subscribe(champions => {
Let arr = [];
Object.keys(champions).map(key => arr.push(new PickQuality(champions[key], 0)));
this.options.next(arr);
})
}
choose(n?: number): PickQuality[] {
return this.options.take(1).sort((a, b) => a.score - b.score);
}
}
答案 2 :(得分:0)
如果您从模板中调用choose(n),则可以添加* ngIf =&#34;选项&#34;到模板中的标签。你必须改变你宣布的方式&#34;选项&#34;所以在加载数据之前它是未定义的。像这样:
options: PickQuality[];
如果您从服务中调用choose(n),我会将其更改为返回Observable或Promise。