Mam listę ogłoszeń materiałów z materiałów kątowych:

  @ViewChildren(MatExpansionPanel)
  matExpansionPanelQueryList: QueryList<MatExpansionPanel>;

I prosta tablica:

questions: [];

Panele rozszerzające są generowane za pomocą *ngFor: uproszczone na przykład:

   <ng-container *ngFor="let question of questions>
            <mat-expansion-panel
               ...

Kiedy rozszerzam tablicę pytań, chcę otworzyć ostatni panel rozszerzający.

     extendQuestion() {
        this.matExpansionPanelQueryList.changes.subscribe(
          change => {
            change.last.open();
          }
        );

        this.questions.push('some-new-item');
      }

Działa to tylko w porządku - wkładam element do tablicy,
Rozbudowane opanowania Get, a nowy panel zostanie utworzony i faktycznie otwiera się - mój problem jest taki, że generuje następujący błąd w konsoli:

ERROR Error: ExpressionChangedAfterItHasBeenCheckedError: Expression has 
changed after it was checked. Previous value: 'mat-expanded: false'. Current 
value: 'mat-expanded: true'.

Czy jest jakiś sposób, aby tego uniknąć?
Próbowałem przy użyciu changeDetectorRef i markForCheck() w subskrypcji, ale komunikat o błędzie nie odszedł (i szczerze, jestem w 100% pewny, jaki jest tutaj dokładny problem).

Aktualizacja : Stackblitz Przykład tego problemu (kliknij przycisk "+").

5
ForestG 22 luty 2019, 11:44

1 odpowiedź

Najlepsza odpowiedź

Z Angularindep:

Jest to ostrzeżny mechanizm umieszczony, aby zapobiec niespójnościom między modelem i interfejsami interfejsu użytkownika, dzięki czemu błędne lub stare dane nie są wyświetlane użytkownikowi na stronie.

Uruchamiana aplikacja kątowa jest drzewem komponentów. Podczas wykrywania zmian kątowy wykonuje kontrole dla każdego elementu, który składa się z następujących operacji w określonej kolejności:

  • Aktualizuj właściwości związane dla wszystkich elementów / dyrektyw dla dzieci
  • Zadzwoń do ngoninit, onchanges i ngdocheck haczyki cyklu na wszystkich elementach / dyrektywach dzieci
  • Zaktualizuj dom dla bieżącego komponentu
  • Uruchom wykrywanie zmiany dla elementu dziecka
  • Wywołaj Ngafterviewinit Hook Lifecycle dla wszystkich elementów / dyrektyw dla wszystkich

Po każdej operacji kanciasty pamięci, jakie wartości wykorzystały działanie. Są one przechowywane w nieruchomości Oldvalues widoku komponentu.

Możesz wywołać hak cyklu życia swojego komponentu przed operacją aktualizacji DOM ..

To powinno działać dla Ciebie:

Możesz dodać constructor dla zmiany (CD) i zadzwoń do tego po change.last.open();

import {ChangeDetectorRef, Component, OnInit, QueryList, ViewChildren} from '@angular/core';

import {MatDialog, MatExpansionPanel} from '@angular/material';

@Component({
selector: 'my-app',
templateUrl: './app.component.html',
styleUrls: [ './app.component.css' ]
})

export class AppComponent {
questions = ['first', 'second'];

constructor(private cd: ChangeDetectorRef) {
    }

@ViewChildren(MatExpansionPanel) matExpansionPanelQueryList: QueryList<MatExpansionPanel>;


extendQuestion() {
        this.matExpansionPanelQueryList.changes.subscribe(
        change => {
            change.last.open();
            this.cd.detectChanges();
        }
        );
        this.questions.push('some-new-item');
    }
}
6
iLuvLogix 22 luty 2019, 09:40