【问题标题】:dataSource.sort broken when *ngIf is applied on table to fix flicker当 *ngIf 应用于表格以修复闪烁时 dataSource.sort 损坏
【发布时间】:2018-12-12 20:17:24
【问题描述】:

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

【问题讨论】:

标签: javascript angular typescript angular-material2


【解决方案1】:

请注意:您必须将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; 
    })

  }

堆栈闪电战

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 定义了一个所谓的摘要循环的概念。这个循环可以 被视为一个循环,在此期间 Angular 检查是否有任何 更改所有 $scope 监视的所有变量。所以如果你 在你的控制器中定义了 $scope.myVar 并且这个变量是 标记为被监视,然后你明确告诉 Angular 在循环的每次迭代中监控 myVar 的变化。

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


请参阅此非 Angular 特定答案,了解 setTmiout() 为何有效。

一个浏览器必须同时做很多事情,而且 其中之一就是执行 JavaScript。但其中一件事 JavaScript 很常用于是要求浏览器构建一个 显示元素。这通常被认为是同步完成的 (特别是因为 JavaScript 不是并行执行的)但是有 不保证是这种情况,并且 JavaScript 没有 明确定义的等待机制。

解决方案是“暂停”JavaScript 执行以让 渲染线程赶上。这就是 setTimeout() 的效果 超时为 0。它就像 C 中的线程/进程产量。 虽然它似乎说“立即运行”,但它实际上给出了 浏览器有机会完成一些非 JavaScript 的事情 一直在等待完成才参加这个新的 JavaScript。

Why is setTimeout(fn, 0) sometimes useful?


总结

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

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

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

【讨论】:

  • OP 的问题是显示空标题以及如果 OP 应用 *ngIf="dataSource.data" 排序中断。
  • 请查看修订版。
  • @Marshal,就像我想要的那样工作并回答问题。但到底是“setTimeout() 在摘要循环中建立链接”。是否有任何在线链接可以阅读此内容。我应该用谷歌搜索什么?谢谢
  • @Gullu 请查看更详细的修订版
猜你喜欢
  • 1970-01-01
  • 2015-07-26
  • 2020-05-07
  • 1970-01-01
  • 1970-01-01
  • 2020-10-11
  • 1970-01-01
  • 2011-09-04
  • 2013-02-22
相关资源
最近更新 更多