第一次加载页面时,角度按钮需要单击两次

时间:2018-09-12 19:53:44

标签: angular async-await angular-promise

我想在Angular 6中创建一个验证函数,该函数根据名称检查对象(菜)是否已存在。 首先,我要执行getDishes方法,以便能够搜索匹配项。

将两种方法合而为一时,一切都很好,但是我想清理一些代码(也是出于学习目的)。

使用下面两种不同方法的代码,在console.log记录名称之前,我需要单击两次。

更新: 经过大量阅读和反复试验后,我自己找到了问题的答案,请参见下面的答案。但是,它看起来是如此简单(太简单了,难道不是真的?),有人可以告诉我这是否确实是一个好的解决方案吗?

初始问题: 所以,谁能告诉我原因:

  1. 我需要单击两次,究竟为什么不及时执行该方法呢?我想这与异步有关?
  2. 我的解决方法是否正确(使用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;
}

2 个答案:

答案 0 :(得分:1)

因为是第一次运行:

  1. 您再次进行“验证”,清空了空盘子
  2. 您调用异步操作实际上是从服务中获取菜品

在第二次单击动作中,异步可能已完成,然后您再次验证了一些设置。 由于您的验证是异步的,因此您应该使用异步验证器来做到这一点。

此代码是异步的!

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();
    ...
 }