我正在使用angular 10,cdktable,并且我面临以下问题。
当我在表上执行搜索时,我的分页不会更新,除非我点击应用程序中的任何位置(它会神奇地更新(。。。
这是一个更改检测问题,我的应用程序正在使用onPush策略。
现在,我的表正在从这个可观测的中获取数据
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>
称自己为分页
pagination.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 || []
})
)
}
但是我不明白为什么这是必要的。
当您使用OnPush
策略时,您需要使用markForCheck()
方法告诉Angular视图已更改,并且应该更新视图。
正如Angular文档所说:
当视图使用OnPush(checkOnce(更改检测策略时,显式地将视图标记为已更改,以便可以再次对其进行检查。
和:
当视图中的输入已更改或事件已激发。调用此方法以确保检查组件,即使这些触发器没有发生。
更新:
itemTotal
未被更新,因为Angular未被告知此更改。我们如何通知?我们需要标记从组件到根的路径,以便检查下一次更改检测运行:
this.itemTotal = res.data.records
this.page = res.data.page
this.changeDetection.markForCheck()
你可以在这里阅读更多。
组件的ChangeDetectionStrategy是OnPush,这意味着只有当@inputs的引用已完全替换为新值。
例如:
var obj = {
test:'test'
};
如果将obj值更新为
obj.test = 'new'
由于参考的对象是相同的。因此,视图将不会更新。为了更新视图,我们需要手动告诉角度来运行变化检测。
为此,请使用markForCheck或detectchanges。
在您的情况下,尽管itemTotal和page都更新了新值,但它指向相同的引用。若要更新视图,需要markForCheck。