При первой загрузке страницы для угловой кнопки требуется два нажатия - PullRequest
0 голосов
/ 12 сентября 2018

Я хочу создать функцию проверки в Angular 6, где она проверяет, существует ли уже объект (блюдо), основываясь на имени. Сначала я хочу выполнить свой метод getDishes, чтобы иметь возможность искать совпадение.

Все отлично работает, когда мои два метода объединены в один, но я хотел очистить некоторый код (также для целей обучения).

С кодом двух разных методов, приведенных ниже, мне нужно сделать два щелчка, прежде чем console.log зарегистрирует имя.

UPDATE: Я сам нашел ответ на вопрос после долгих чтений, проб и ошибок, см. Мой ответ ниже. Однако, это кажется таким простым (слишком простым, чтобы быть правдой?), Кто-нибудь может сказать мне, действительно ли это хорошее решение?

Начальный вопрос: Итак, кто-нибудь может сказать, почему:

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

Я провел некоторое исследование, но не смог найти ответ для себя. Заранее спасибо за помощь!

EDIT: После комментария Антониосса я провел дополнительное исследование и адаптировал свой код. Однако, это все еще не работает, и 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 голосов
/ 31 октября 2018

Итак ... после долгих проб и ошибок, чтения и пробования множества методов с использованием async и await я наконец нашел решение.

Мне просто нужно было добавить toPromise () после службы,По какой-то причине это кажется простым, действительно ли это хорошее решение?

  getExistingDishes() {
    let existingDishes = this.dishService.getDishes().toPromise();
    return existingDishes;
  }

И метод, в котором оно используется:

 async addTest() {
    let existingDishes = await this.getExistingDishes();
    ...
 }
0 голосов
/ 12 сентября 2018

Потому что при первом запуске:

  1. Вы выполняете проверку снова EMPTY Dish array
  2. Вы вызываете асинхронное действие, чтобы фактически ВЫБРАТЬ блюдо из сервиса

При втором щелчке, асинхронное выполнение, вероятно, завершается, и затем вы снова проверяете некоторый набор блюд. Поскольку ваша валидация асинхронная, вы должны использовать асинхронные валидаторы, чтобы сделать это.

Этот код является асинхронным !!

this.dishService.getDishes()
  .subscribe(dishes => {
    this.dishes = dishes;
  });
return this.dishes;

поэтому при первом запуске вы только START this.dishService.getDishes() запрос, но вы не ждете его завершения, поэтому вы мгновенно возвращаете this.dishes, и это пусто.

Через некоторое время запрос завершается (ajax помните?) И вызывается подписка - подписка устанавливает массив this.dishes для любой службы, которая была возвращена. Вот почему второй запуск использует непустой массив блюд. Но в любом случае это не сработает, так как если вы быстро добавите 2 раза одно и то же блюдо, проверка пройдет, так как он будет использовать массив старых блюд, а не тот, который содержит добавленное блюдо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...