Angular 10 — Изменить порядок выполнения в AfterViewInit при использовании подписки

#angular #typescript #angular-material #subscription #angular10

#angular #typescript #angular-материал #подписка #angular10

Вопрос:

У меня есть этот перехват жизненного цикла ngAfterViewInit:

 ngAfterViewInit() {
    this.sort.sortChange.subscribe(() => this.paginator.pageIndex = 0);

    this.subscription = this.dataService.dataChanged
      .subscribe(
        () => {
          this.getData();
        }
      );

    this.getData();
  }
  

Я хочу, чтобы подписка запускалась до того, this.getData() что находится за пределами подписки, и только если этого не произошло, я бы хотел, чтобы this.getData() что находится за пределами подписки запускалось.

Как я могу это сделать? Помещение этого в ngOnInit не работает, потому что это таблица с разбиением на страницы, и это работает только после рендеринга страницы. Мне нужно иметь подписку на тот момент, когда пользователь добавляет новые данные в таблицу, и я хочу, чтобы они были видны автоматически.

Отредактировано Если я запускаю код, подобный написанному выше, то при первом переходе на страницу мои данные правильно загружаются в мою таблицу с разбивкой на страницы с сервера. Затем пользователь может добавить новый элемент данных, используя форму, которая находится в другом компоненте. Когда пользователь заканчивает добавлять новый элемент, он возвращается к этой таблице. Как это выглядит сейчас, таблица сначала загружается без нового добавления, а затем перезагружается с новым дополнением. Чего я хотел, так это чтобы первая загрузка не была видна пользователю — чтобы при обратном переходе они сразу видели правильные данные.

Комментарии:

1. при использовании subscribe выполнение выполняется синхронно, поэтому вы не можете предсказать, будет ли оно выполнено до или после кода вне подписки. Почему вы просто не удалите последнюю строку? строка this.getData в подписке будет выполняться каждый раз, когда ваш наблюдаемый объект dataChanged выдает значение

2. @GauthierT., проблема в том, что если я удалю эту последнюю строку, метод getData () никогда не вызывается, потому что подписка выдается только после того, как пользователь вручную добавит данные в мой источник данных. Есть мысли?

Ответ №1:

Вам необходимо изменить поток вашего кода, поскольку подписки являются асинхронными.

  private callGetData: boolean

 ngAfterViewInit() {

    this.callGetData = true;

    this.sort.sortChange.subscribe(() => {
       this.paginator.pageIndex = 0;
       if(this.callGetData) this.getData();
       this.callGetData = false;
    })

    this.subscription = this.dataService.dataChanged
      .subscribe(
        () => {
          this.getData();
        }
      );
  }
  

Таким образом, вы будете вызывать его getData() только после ngAfterViewInit() выполнения, а не каждый раз, когда подписка получает событие.

или вы можете удалить флаг, если хотите getData() также внутри подписки.

Надеюсь, это сработает!

Комментарии:

1. прежде всего, спасибо. Проблема сейчас в том, что подписка на dataChanged не всегда выдается, поэтому, когда я впервые перехожу на эту страницу, данные с сервера просто не поступают. Он выдается только после добавления нового элемента данных. Есть идеи?

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

3. sortChange() не отправляется до тех пор, пока данные не будут загружены. Данные загружаются только в том случае, если запущен this.getData() метод, но таким образом он никогда не запускается. Сейчас я собираюсь отредактировать свой вопрос, чтобы он содержал лучшее объяснение.

4. Я отредактировал свой вопрос — надеюсь, это даст лучшее понимание того, чего я хочу.

5. когда добавляется новая запись, вы можете просто добавить ее в строки таблицы вашей таблицы (после завершения добавления записи). если его обновить, вы можете взять id и заменить строку новыми данными.