简体   繁体   English

为什么我需要标记检查? angular

[英]Why do I need mark for check ? angular

I am using angular 10, cdktable and I face the following problem.我正在使用 angular 10,cdktable,我面临以下问题。

when I execute a search on a table, my pagination do not update unless I click anywhere in the app (that it magically update)...当我在表格上执行搜索时,除非我单击应用程序中的任何位置(它神奇地更新),否则我的分页不会更新...

This is a change detection problem, my app is using onPush strategy.这是一个变更检测问题,我的应用程序正在使用 onPush 策略。

now, my table is getting data from this observable现在,我的表正在从这个 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 || []
    })
  )
}

note that here I am updating the total number of item and the page.请注意,这里我正在更新项目和页面的总数。

now, this is passed to the table component现在,这被传递给表格组件

table.component.ts table.component.ts

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

which call itself the pagination它称自己为分页

pagination.ts:分页.ts:

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

If I follow the logic, the itemTotal change, it is passed as input to table and to pagination so it should trigger a change.如果我遵循逻辑, itemTotal更改,它将作为输入传递给tablepagination ,因此它应该触发更改。

Everything works if I do如果我这样做,一切都会奏效

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 || []
    })
  )
}

But I do not understand why is this necessary.但我不明白为什么这是必要的。

When you use OnPush strategy, then you need to use markForCheck() method to say Angular that view is changed and view should be updated.当你使用OnPush策略时,你需要使用markForCheck()方法来告诉 Angular 视图改变并且视图应该被更新。

As Angular docs says:正如 Angular 文档所说:

When a view uses the OnPush (checkOnce) change detection strategy, explicitly marks the view as changed so that it can be checked again.当视图使用 OnPush (checkOnce) 更改检测策略时,显式将视图标记为已更改,以便可以再次对其进行检查。

and:和:

Components are normally marked as dirty (in need of rerendering) when inputs have changed or events have fired in the view.当输入已更改或视图中已触发事件时,组件通常会被标记为脏(需要重新渲染)。 Call this method to ensure that a component is checked even if these triggers have not occured.调用此方法以确保即使未发生这些触发器也会检查组件。

UPDATE:更新:

itemTotal is not updated because Angular is not informed about this change. itemTotal未更新,因为 Angular 未获悉此更改。 How we can inform?我们如何告知? We need to mark the path from our component until root to be checked for the next change detection run:我们需要标记从组件到 root 的路径,以检查下一次更改检测运行:

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

You can read more here. 你可以在这里阅读更多。

ChangeDetectionStrategy of your component is OnPush which means the change detection will run only when the references of the @inputs has been completely replaced with a new value.您的组件的 ChangeDetectionStrategy 是 OnPush ,这意味着只有在 @inputs 的引用完全被新值替换时才会运行更改检测。

For example:例如:

var obj = {
    test:'test'
};

If you update the obj value as如果将 obj 值更新为

obj.test = 'new'

angular will not run the change detection in the above case since the reference of the obj is same. angular 在上述情况下不会运行变化检测,因为 obj 的引用是相同的。 As a result, view will not be updated.因此,视图将不会更新。 To update the view, manually we need to tell the angular to run change detection.要更新视图,我们需要手动告诉 angular 运行更改检测。

For this, use markForCheck or detectchanges.为此,请使用 markForCheck 或 detectchanges。

In your case, Eventhough both the itemTotal and page has updated with new value but it points to the same reference.在您的情况下,尽管 itemTotal 和 page 都已更新为新值,但它指向相同的引用。 To update the view, markForCheck is needed.要更新视图,需要 markForCheck。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM