dataSource.sort не работает, когда * ngIf применяется к таблице для устранения мерцания - PullRequest
0 голосов
/ 12 декабря 2018

Относительно таблицы материалов в угловых 2.В моем ngonit () у меня есть this.mydatasource.sort = this.sort.Сортировка работает, но пока данные загружаются, я кратко вижу заголовок таблицы (мерцание), а затем появляется вся таблица.Как только я создаю таблицу ngif = "mytabledata", мерцание заголовка исчезает, и вся таблица с данными появляется сразу, как я хочу, но теперь сортировка не работает, так как при попадании в ngonit мои данные не загружаются.(данные загружаются по ngonchanges, который запускается при изменении входного параметра).Как я могу исправить эту загадку?

1 Ответ

0 голосов
/ 13 декабря 2018

Обратите внимание: Вам нужно обернуть this.dataSource.sort = this.sort в setTimeout(), чтобы установить ссылку в цикле дайджеста, без него @ViewChild(MatSort) sort: MatSort не определено из-за *ngIf.

ngOnChanges() {
    const ELEMENT_DATA1: PeriodicElement[] = [
      { position: 1, name: 'Hydrogen', weight: 1.0079, symbol: 'H' },
      { position: 2, name: 'Helium', weight: 4.0026, symbol: 'He' },
      { position: 3, name: 'Lithium', weight: 6.941, symbol: 'Li' },
      { position: 4, name: 'Beryllium', weight: 9.0122, symbol: 'Be' },
      { position: 5, name: 'Boron', weight: 10.811, symbol: 'B' },
      { position: 6, name: 'Carbon', weight: 12.0107, symbol: 'C' },
      { position: 7, name: 'Nitrogen', weight: 14.0067, symbol: 'N' },
      { position: 8, name: 'Oxygen', weight: 15.9994, symbol: 'O' },
      { position: 9, name: 'Fluorine', weight: 18.9984, symbol: 'F' },
      { position: 10, name: 'Neon', weight: 20.1797, symbol: 'Ne' },

    ];
    this.dataSource.data = ELEMENT_DATA1;

    console.log(this.sort) //undefined
    setTimeout(() => {
      console.log(this.sort) //not undefined
      this.dataSource.sort = this.sort; 
    })

  }

Stackblitz

https://stackblitz.com/edit/angular-table-sort-not-working-pv8yap?embed=1&file=app/table-sorting-example.ts


Цикл дайджеста - это термин, определенный в днях AngularJS ... см. Этот SO-ответдля получения дополнительной информации .... Поверьте, теперь это чаще называют Change Detection

Angular определяет концепцию так называемого цикла дайджеста.Этот цикл можно рассматривать как цикл, во время которого Angular проверяет, есть ли какие-либо изменения во всех переменных, наблюдаемых всеми $ scopes.Поэтому, если в вашем контроллере определен $ scope.myVar, и эта переменная была помечена для отслеживания, то вы явно указываете Angular отслеживать изменения на myVar на каждой итерации цикла.

Angular - что запускает цикл дайджеста для двухсторонних привязок данных?


См. Этот неугловой специфический ответ, почему setTmiout() работает.

AБраузер должен делать сразу несколько вещей, и только одна из них - выполнять JavaScript.Но одна из вещей, для которой очень часто используется JavaScript - это попросить браузер создать элемент отображения.Часто предполагается, что это делается синхронно (в частности, поскольку JavaScript не выполняется параллельно), но нет никакой гарантии, что это так, и JavaScript не имеет четко определенного механизма ожидания.

Решение состоит в том, чтобы«приостановить» выполнение JavaScript, чтобы потоки рендеринга наверстали упущенное.И это эффект, который делает setTimeout () с таймаутом 0.Это похоже на выход потока / процесса в C. Хотя кажется, что он говорит «запустите это немедленно», на самом деле он дает браузеру возможность завершить некоторые вещи, не связанные с JavaScript, которые ожидали завершения, прежде чем приступить к этому новому фрагменту JavaScript..

Почему setTimeout (fn, 0) иногда полезен?


В итоге

Обнаружение цикла / изменения дайджеста обычно относится к задаче, не связанной с Angular, такой как рендеринг элемента представления и т. Д. ... в этом примере ваш ngOnchange() не ожидал потоков рендеринга, созданных вашим *ngIf, становящимся истинным,завершить в браузере ... и пытался привязать ссылку @ViewChild view до того, как она была на самом деле в DOM ...

  • Причина, по которой console.log был не определен
  • А другой внутри setTimeout() не было

Обтекание этой строки кода в setTimeout() заставило его ждать, пока браузер завершит свою задачу рендеринга, созданную вашим *ngIf.

...