dataSource.sort 在 table 上应用 *ngIf 修复闪烁时损坏

dataSource.sort broken when *ngIf is applied on table to fix flicker

关于 material table angular 2 。在我的 ngonit() 中,我有 this.mydatasource.sort = this.sort。排序有效,但在加载数据时,我短暂地看到 table header(闪烁),然后出现整个 table。一旦我执行了 table ngif="mytabledata",header 闪烁就会消失,整个 table 数据会像我想要的那样立即出现,但现在排序不起作用因为当它点击 ngonit 时,我的数据没有加载。 (数据加载到输入参数更改时触发的 ngonchanges 上)。我该如何解决这个难题?

请注意: 您必须将 this.dataSource.sort = this.sort 包裹在 setTimeout() 中才能在摘要循环中建立 link,否则,由于 *ngIf.

@ViewChild(MatSort) sort: MatSort 未定义
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


Digest Cycle 是在 AngularJS 时代定义的一个术语...请参阅此 SO 答案以获取更多信息....相信它现在更常被称为 Change Detection

Angular defines a concept of a so called digest cycle. This cycle can be considered as a loop, during which Angular checks if there are any changes to all the variables watched by all the $scopes. So if you have $scope.myVar defined in your controller and this variable was marked for being watched, then you are explicitly telling Angular to monitor the changes on myVar in each iteration of the loop.

Angular - what triggers the digest cycle for 2 way data bindings?


查看此非 Angular 特定答案,了解 setTmiout() 为何有效。

A browser has to do a number of things pretty much all at once, and just one of those is execute JavaScript. But one of the things JavaScript is very often used for is to ask the browser to build a display element. This is often assumed to be done synchronously (particularly as JavaScript is not executed in parallel) but there is no guarantee this is the case and JavaScript does not have a well-defined mechanism for waiting.

The solution is to "pause" the JavaScript execution to let the rendering threads catch up. And this is the effect that setTimeout() with a timeout of 0 does. It is like a thread/process yield in C. Although it seems to say "run this immediately" it actually gives the browser a chance to finish doing some non-JavaScript things that have been waiting to finish before attending to this new piece of JavaScript.

Why is setTimeout(fn, 0) sometimes useful?


总结

Digest Cycle/Change 检测通常指的是非 Angular 浏览器相关任务,例如呈现视图项等...在此示例中,您的 ngOnchange() 没有等待由您的 *ngIf 创建的渲染线程变为 true,在浏览器中完成...并试图在 @ViewChild 视图引用实际存在于 DOM 之前绑定它。 .

  • 原因一 console.log 未定义
  • setTimeout() 的另一个内部不是

将那行代码包装在 setTimeout() 中使其等待浏览器完成由您的 *ngIf 创建的渲染任务。