1

我正在使用 angular 10,cdktable,我面临以下问题。

当我在表格上执行搜索时,除非我单击应用程序中的任何位置(它神奇地更新),否则我的分页不会更新...

这是一个变更检测问题,我的应用程序正在使用 onPush 策略。

现在,我的表正在从这个 observable 中获取数据

connect(): Observable < Advertisers_advertisers_rows[] > {
  return this.store.pipe(
    select(advertiserPage),
    map((res) => {
      this.itemTotal = res.data.records
      this.page = res.data.page
      return res?.data?.rows || []
    })
  )
}

请注意,这里我正在更新项目和页面的总数。

现在,这被传递给表格组件

table.component.ts

<app-table
  [dataSource]="this"
  [pagination]="paginationOptions"
  (pageChange)="loadPage($event)"
  [itemTotal]="itemTotal"
></app-table>

它称自己为分页

分页.ts:

<app-table-pagination
  *ngIf="pagination"
  [options]="pagination"
  [(page)]="page"
  (pageChange)="pageChange.emit($event)"
  [total]="itemTotal"
></app-table-pagination>

如果我遵循逻辑,则itemTotal更改将作为输入传递给table和,pagination因此它应该触发更改。

如果我这样做,一切都会奏效

connect(): Observable < Advertisers_advertisers_rows[] > {
  return this.store.pipe(
    select(advertiserPage),
    map((res) => {
      this.itemTotal = res.data.records
      this.page = res.data.page
      this.changeDetection.markForCheck()
      return res?.data?.rows || []
    })
  )
}

但我不明白为什么这是必要的。

4

2 回答 2

2

当您使用OnPush策略时,您需要使用markForCheck()方法说 Angular 视图已更改并且视图应该更新。

正如 Angular 文档所说:

当视图使用 OnPush (checkOnce) 更改检测策略时,显式将视图标记为已更改,以便可以再次对其进行检查。

和:

当输入已更改或视图中已触发事件时,组件通常会被标记为脏(需要重新渲染)。调用此方法以确保即使未发生这些触发器也会检查组件。

更新:

itemTotal没有更新,因为 Angular 没有收到有关此更改的通知。我们如何告知?我们需要标记从组件到 root 的路径,以检查下一次更改检测运行:

this.itemTotal = res.data.records
this.page = res.data.page
this.changeDetection.markForCheck()

你可以在这里阅读更多。

于 2020-07-29T08:57:02.317 回答
0

您的组件的 ChangeDetectionStrategy 是 OnPush ,这意味着只有在 @inputs 的引用完全被新值替换时才会运行更改检测。

例如:

var obj = {
    test:'test'
};

如果将 obj 值更新为

obj.test = 'new'

在上述情况下,角度不会运行变化检测,因为 obj 的引用是相同的。因此,视图将不会更新。要更新视图,我们需要手动告诉 Angular 运行更改检测。

为此,请使用 markForCheck 或 detectchanges。

在您的情况下,尽管 itemTotal 和 page 都已更新为新值,但它指向相同的引用。要更新视图,需要 markForCheck。

于 2020-07-29T09:20:45.417 回答