Проблема закрытия моего matDialog в моей функции ngDoCheck () Angular - PullRequest
0 голосов
/ 09 мая 2019

У меня проблема с закрытием моего matDialog углового материала в моей функции ngDoCheck().

РЕДАКТИРОВАТЬ: StackBlitz ЗДЕСЬ

Объяснение:

На моей главной странице есть кнопка, которая открывает matDialog, чтобы извлечь или нет данные в Excel файл.В моем matDialog у меня есть две кнопки.Один, чтобы закрыть matDialog, и другой, который запускает функцию extractWallet(), чтобы восстановить данные в базе данных.

В этой функции я отключаю мои кнопки с помощью переменной waitExtraction и отключаю закрытиеmatDialog до завершения извлечения.

Мои loadInvoiceExtractionXXX() методы позволяют мне восстановить данные в моей базе данных, и после получения данных completedExtraction, установленный на [false, false, false], установлен на true вкл.индекс (0, 1 или 2), соответствующий функции.

В моем ngOnInit() данные принимаются через Observer и сохраняются в локальной переменной.Таким образом, новые данные получаются после выполнения loadInvoiceExtractionXXX() в extractWallet().

Моя проблема возникает здесь.У меня есть функция ngDoCheck(), которая проверяет, когда все три данные получены с this.completedExtraction=[true, true, true].Мой Excel файл хорошо создан и загружен в браузер.Извлечение завершено, теперь я хочу закрыть matDialog с помощью this.dialogRef.close().

, но отображается следующая ошибка: enter image description here

Ошибка: ExpressionChangedAfterItHasBeenCheckedError : Выражение изменилось после его проверки.

Предыдущее значение: '@dialogContainer: enter'.Текущее значение: '@dialogContainer: exit'.

Я попытался закрыть matDialog в ngAfterViewChecked(), но отображается та же ошибка.Если у кого-нибудь есть решение предложить мне закрыть matDialog после извлечения, мне будет интересно.

Я предоставлю свой код в ваше распоряжение:

export class ExtractWalletComponent implements OnInit, DoCheck, OnDestroy {

  private subscription$: Subscription = new Subscription();

  selectedWallet: Wallet;
  waitExtraction: boolean;
  completedExtraction: boolean[];

  invoiceProduct: InvoiceExtractionProduct[];
  invoiceSupport: InvoiceExtractionSupport[];
  invoiceTraining: InvoiceExtractionTraining[];

  constructor(public dialogRef: MatDialogRef<ExtractWalletComponent>,
              public storeWallets: WalletsComponentStore,
              public snackBar: MatSnackBar) { }

  ngOnInit(): void {
    this.waitExtraction = false;
    this.completedExtraction = [false, false, false];

    this.subscription$.add(this.storeWallets.selectedWallet$.subscribe(wallet => this.selectedWallet = wallet));
    this.subscription$.add(this.storeWallets.invoiceExtractionProduct$.subscribe(invoiceProduct => this.invoiceProduct = invoiceProduct));
    this.subscription$.add(this.storeWallets.invoiceExtractionSupport$.subscribe(invoiceSupport => this.invoiceSupport = invoiceSupport));
    this.subscription$.add(this.storeWallets.invoiceExtractionTraining$.subscribe(invoiceTraining => this.invoiceTraining = invoiceTraining));
  }

  ngDoCheck(): void {
    if(this.completedExtraction[0] == true && this.completedExtraction[1] == true && this.completedExtraction[2] == true) {
      this.completedExtraction[0] = false;
      this.completedExtraction[1] = false;
      this.completedExtraction[2] = false;
      this.dialogRef.disableClose = false;

      const wb: XLSX.WorkBook = XLSX.utils.book_new();
      const ws1: XLSX.WorkSheet = XLSX.utils.json_to_sheet(this.invoiceProduct);
      const ws2: XLSX.WorkSheet = XLSX.utils.json_to_sheet(this.invoiceSupport);
      const ws3: XLSX.WorkSheet = XLSX.utils.json_to_sheet(this.invoiceTraining);

      XLSX.writeFile(wb, this.selectedWallet.user.num_seller + '_' + this.selectedWallet.period.month +
                          '_' + this.selectedWallet.period.year + '_' + this.selectedWallet.id + '.xlsx');

      this.dialogRef.close(); //<-- ERROR
    }
  }

  ngOnDestroy(): void {
    this.subscription$.unsubscribe();
    this.storeWallets.clearExtraction();
  }

  extractWallet(): void {
    this.waitExtraction = true;
    this.dialogRef.disableClose = true;
    this.snackBar.open('Extraction en cours', 'OK', { duration: 5000 });

    this.storeWallets.loadInvoiceExtractionProduct(this.selectedWallet).subscribe(
      res => {
        if(res) { this.completedExtraction[0] = true;}
      },
      err => { console.error(err); this.dialogRef.close(); this.snackBar.open('Echec de l\'extraction', 'OK', { duration: 2000 }); }
    );

    this.storeWallets.loadInvoiceExtractionSupport(this.selectedWallet).subscribe(
      res => {
        if(res) { this.completedExtraction[1] = true; }
      },
      err => { console.error(err); this.dialogRef.close(); this.snackBar.open('Echec de l\'extraction', 'OK', { duration: 2000 }); }
    );

    this.storeWallets.loadInvoiceExtractionTraining(this.selectedWallet).subscribe(
      res => {
        if(res) { this.completedExtraction[2] = true; }
      },
      err => { console.error(err); this.dialogRef.close(); this.snackBar.open('Echec de l\'extraction', 'OK', { duration: 2000 }); }
    );
  }
}

Заранее благодарю за помощь.

PS: Извините за мой английский (перевод Google).

1 Ответ

1 голос
/ 09 мая 2019

Ну, проблема именно в том, что она говорит вам: вы что-то меняете во время цикла обнаружения изменений. Вам нужно поместить изменение вне цикла, например, так:

ngDoCheck(): void {
   if(this.completedExtraction[0] == true && this.completedExtraction[1] == true && this.completedExtraction[2] == true) {
      // omitted

      // Run after change detection
      setTimeout(() => this.dialogRef.close());

   }
}

Но я думаю, что основная проблема заключается в том, что вы используете ловушку жизненного цикла ngDoCheck. Почему бы вам просто не отреагировать на Observables?

combineLatest([
   this.storeWallets.loadInvoiceExtractionProduct(this.selectedWallet)
      .pipe(/* Add your catchError logic for only this observable */),
   this.storeWallets.loadInvoiceExtractionSupport(this.selectedWallet),
   this.storeWallets.loadInvoiceExtractionTraining(this.selectedWallet),
]).pipe(
   filter(results => results.every(res => !!res))
).subscribe(results => {
   // Called when all 3 returned positively
})
...