Angular。 HTML 在页面上重新路由后不更新
Angular. HTML doesn't update afret re route on page
问题如下。第一次初始化页面时,所有数据都会正确更新。在 HTML 中,我使用的是简单的 table:
<mat-table [dataSource]="sumDataSource">
但是,如果在第一次初始化后,您转到另一个页面并return返回到原始页面,则数据不再更新。虽然所有事件都已正确处理,但服务器 return 的新数据。在组件本身中,sumDataSource 变量的值也发生了变化,但旧数据仍保留在 HTML.
应用-routing.module.ts
const routes: Routes = ....
@NgModule({
imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],
exports: [RouterModule]
})
export class AppRoutingModule { }
在组件中,数据更新是这样的
ngOnInit(): void {
this.emitter();
this.conditionDefiner();
this.initMoneyAct();
this.mapData();
}
mapData() {
if (this.dateCondition) {
this.homepageService.getMoneyAct().subscribe(res => {
this.moneyAct = res as MoneyAct;
if (this.houseCondition) {
this.mapPeriodTable(this.moneyAct);
}
this.mapSumTable(this.moneyAct);
});
}
}
mapSumTable(moneyAct: MoneyAct) {
this.sumDataSource = [];
this.sumDataSource.push(moneyAct.cashBoxSummary);
}
mapPeriodTable(moneyAct: MoneyAct) {
this.periodDataSource = [];
for (let key in moneyAct.moneyByMonth) {
this.periodDataSource.push({ group: key });
for (let index = 0; index < moneyAct.moneyByMonth[key].length; index++) {
const row: CashBoxDetails = moneyAct.moneyByMonth[key][index];
this.periodDataSource.push({
arrival: row.arrival,
countAdults: row.countAdults,
countDays: row.countDays,
costPerDay: row.costPerDay,
needToPay: row.needToPay,
received: row.received,
prePayment: row.prePayment,
isPaind: row.isPaind,
phoneNumber: row.phoneNumber
});
}
}
}
所有这些仅在您第一次访问该页面时有效。
Angular CLI: 11.1.4
Node: 14.15.0
OS: win32 x64
Angular: 11.1.2
... animations, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, router
Ivy Workspace: Yes
Package Version
------------------------------------------------------------
@angular-devkit/architect 0.1001.1
@angular-devkit/core 10.1.1
@angular/cdk 10.2.1
@angular/cli 11.1.4
@angular/fire 6.0.3
@angular/material 10.2.1
@angular/material-moment-adapter 11.2.0
@schematics/angular 11.1.4
@schematics/update 0.1101.4
rxjs 6.6.3
typescript 4.0.2
更新
找到问题所在了。但我不明白为什么。在我的案例中更改组件模型的事件在另一个组件中调用。我是通过发射器做到的。
有事件的组件
onHouseChange(id: string) {
localStorage.setItem(GLOBAL_VARIABLE.SELECTED_HOUSE, id);
this.eventEmitterService.runMoneyAct();
}
EventEmitterService
export class EventEmitterService {
invokeMoney = new EventEmitter();
subsMoney: Subscription;
constructor() { }
sub(subscription: Subscription) {
if (this.subsHome == undefined) {
this.subsHome = subscription
}
}
runMoneyAct(){
this.invokeMoney.emit();
}
更新数据的组件
emitter() {
if (this.eventEmitterService.subsMoney == undefined) {
this.eventEmitterService.subsMoney = this.eventEmitterService.invokeMoney.subscribe(() => {
this.ngOnInit();
});
}
}
如果把事件调用放在组件本身,就没有问题
根据Angular material的官方文档:
"由于table优化了性能,它不会自动检查对数据数组的更改。相反,当在数据数组上添加、删除或移动对象时,您可以触发更新通过调用它的 renderRows() 方法到 table 的渲染行。
您必须调用 table 的 renderRows() 函数来检查数组是否已更新。
问题如下。第一次初始化页面时,所有数据都会正确更新。在 HTML 中,我使用的是简单的 table:
<mat-table [dataSource]="sumDataSource">
但是,如果在第一次初始化后,您转到另一个页面并return返回到原始页面,则数据不再更新。虽然所有事件都已正确处理,但服务器 return 的新数据。在组件本身中,sumDataSource 变量的值也发生了变化,但旧数据仍保留在 HTML.
应用-routing.module.ts
const routes: Routes = ....
@NgModule({
imports: [RouterModule.forRoot(routes, { relativeLinkResolution: 'legacy' })],
exports: [RouterModule]
})
export class AppRoutingModule { }
在组件中,数据更新是这样的
ngOnInit(): void {
this.emitter();
this.conditionDefiner();
this.initMoneyAct();
this.mapData();
}
mapData() {
if (this.dateCondition) {
this.homepageService.getMoneyAct().subscribe(res => {
this.moneyAct = res as MoneyAct;
if (this.houseCondition) {
this.mapPeriodTable(this.moneyAct);
}
this.mapSumTable(this.moneyAct);
});
}
}
mapSumTable(moneyAct: MoneyAct) {
this.sumDataSource = [];
this.sumDataSource.push(moneyAct.cashBoxSummary);
}
mapPeriodTable(moneyAct: MoneyAct) {
this.periodDataSource = [];
for (let key in moneyAct.moneyByMonth) {
this.periodDataSource.push({ group: key });
for (let index = 0; index < moneyAct.moneyByMonth[key].length; index++) {
const row: CashBoxDetails = moneyAct.moneyByMonth[key][index];
this.periodDataSource.push({
arrival: row.arrival,
countAdults: row.countAdults,
countDays: row.countDays,
costPerDay: row.costPerDay,
needToPay: row.needToPay,
received: row.received,
prePayment: row.prePayment,
isPaind: row.isPaind,
phoneNumber: row.phoneNumber
});
}
}
}
所有这些仅在您第一次访问该页面时有效。
Angular CLI: 11.1.4
Node: 14.15.0
OS: win32 x64
Angular: 11.1.2
... animations, common, compiler, compiler-cli, core, forms
... language-service, localize, platform-browser
... platform-browser-dynamic, router
Ivy Workspace: Yes
Package Version
------------------------------------------------------------
@angular-devkit/architect 0.1001.1
@angular-devkit/core 10.1.1
@angular/cdk 10.2.1
@angular/cli 11.1.4
@angular/fire 6.0.3
@angular/material 10.2.1
@angular/material-moment-adapter 11.2.0
@schematics/angular 11.1.4
@schematics/update 0.1101.4
rxjs 6.6.3
typescript 4.0.2
更新
找到问题所在了。但我不明白为什么。在我的案例中更改组件模型的事件在另一个组件中调用。我是通过发射器做到的。
有事件的组件
onHouseChange(id: string) {
localStorage.setItem(GLOBAL_VARIABLE.SELECTED_HOUSE, id);
this.eventEmitterService.runMoneyAct();
}
EventEmitterService
export class EventEmitterService {
invokeMoney = new EventEmitter();
subsMoney: Subscription;
constructor() { }
sub(subscription: Subscription) {
if (this.subsHome == undefined) {
this.subsHome = subscription
}
}
runMoneyAct(){
this.invokeMoney.emit();
}
更新数据的组件
emitter() {
if (this.eventEmitterService.subsMoney == undefined) {
this.eventEmitterService.subsMoney = this.eventEmitterService.invokeMoney.subscribe(() => {
this.ngOnInit();
});
}
}
如果把事件调用放在组件本身,就没有问题
根据Angular material的官方文档:
"由于table优化了性能,它不会自动检查对数据数组的更改。相反,当在数据数组上添加、删除或移动对象时,您可以触发更新通过调用它的 renderRows() 方法到 table 的渲染行。
您必须调用 table 的 renderRows() 函数来检查数组是否已更新。