我想在Angular 6中创建一个验证函数,该函数根据名称检查对象(菜)是否已存在。 首先,我要执行getDishes方法,以便能够搜索匹配项。
将两种方法合而为一时,一切都很好,但是我想清理一些代码(也是出于学习目的)。
使用下面两种不同方法的代码,在console.log记录名称之前,我需要单击两次。
更新: 经过大量阅读和反复试验后,我自己找到了问题的答案,请参见下面的答案。但是,它看起来是如此简单(太简单了,难道不是真的?),有人可以告诉我这是否确实是一个好的解决方案吗?
初始问题: 所以,谁能告诉我原因:
我的解决方法是否正确(使用OnInit中的代码)?最后,添加新菜时始终需要进行验证。
addDishWithDishExistValidation(): void {
let dish = this.dishForm.value;
for (let existingDish of this.getDishes()) {
if (dish.name == existingDish.name) {
console.log(existingDish.name);
}
}
}
getDishes(): Dish[] {
this.dishService.getDishes()
.subscribe(dishes => {
this.dishes = dishes;
});
return this.dishes;
}
但是,当我将此零件放在OnInit中时,一切正常:
this.dishService.getDishes()
.subscribe(dishes => {
this.dishes = dishes;
});
我做了很多研究,但找不到适合自己的答案。预先感谢您的帮助!
编辑: 在Antoniosss发表评论之后,我做了一些额外的研究并修改了我的代码。但是,它仍然不起作用,console.log(dishList)确实显示了第一次单击后该数组仍然为空。我该怎么解决?
async addDishWithDishExistValidation(): Promise<void> {
let dish = this.dishForm.value;
let dishList = await this.getDishes();
console.log(dishList);
for (let existingDish of dishList) {
if (dish.name == existingDish.name) {
console.log(existingDish.name);
}
}
}
async getDishes(): Promise<Dish[]> {
await this.dishService.getDishes()
.subscribe(dishes => {
this.dishes = dishes;
});
return this.dishes;
}
答案 0 :(得分:1)
因为是第一次运行:
在第二次单击动作中,异步可能已完成,然后您再次验证了一些设置。 由于您的验证是异步的,因此您应该使用异步验证器来做到这一点。
此代码是异步的!
this.dishService.getDishes()
.subscribe(dishes => {
this.dishes = dishes;
});
return this.dishes;
因此,在第一次运行时,您仅会发出START this.dishService.getDishes()
请求,但您不必等待它完成,因此您会立即返回this.dishes
且为空。
一段时间后,请求完成(ajax还记得吗?),并调用了预订-预订会将this.dishes
数组设置为返回的任何服务。这就是为什么第二轮使用非空皿阵列的原因。但这无论如何都不会起作用,就像您快速添加同一盘的2倍一样,验证将通过,因为它将使用OLD盘阵列,而不是包含添加盘的阵列。
答案 1 :(得分:0)
所以..经过大量的试验和错误,并使用异步和等待方法阅读并尝试了很多方法,我终于找到了解决方法。
我只需要在服务后添加toPromise()。出于某种原因,这似乎很简单,这真的是一个好的解决方案吗?
getExistingDishes() {
let existingDishes = this.dishService.getDishes().toPromise();
return existingDishes;
}
以及使用它的方法:
async addTest() {
let existingDishes = await this.getExistingDishes();
...
}