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
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
创建的渲染任务。
关于 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
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
创建的渲染任务。