我试图从 Angular Router 12.2.0 中找出一个奇怪的行为。
我正在使用 websockets 实时更新表格。只要我不使用路由器,一切都会按预期工作(通过单击具有[routerLink]
属性的锚标记或通过调用router.navigate
方法)。
重现步骤
- 导航到托管表格的组件,比如说
/employees
- 确认表格实时更新
- 导航离开
- 回来
/employees
- 该表现在被页面加载时收到的数据冻结
问题不是来自套接字。该组件不断从服务器接收数据并按预期更新模型。只有 GUI 与模型不同步。
奇怪的是,如果我手动触发完全相同的更新(即通过执行绑定到按钮的功能),UI 将反映更改。
恢复实时更新的唯一方法是使用F5
.
这种行为与“角区”有关吗? 为什么只有当我使用角度路由器导航时才会发生这种行为?到底是怎么回事?
代码示例
代码很简单。我只是通过提供 uri 和回调来订阅 STOMP Broker 位置。我在回调中更新模型。模型(一个简单的数组)使用*ngFor
指令在视图中呈现。
// callback executed everytime a message from the server is received
const callback = (message: Message) => {
const e: Employee = JSON.parse(message.body);
// update the model
this.employees.push(e);
}
this.stompClient.subscribe(uri, callback, headers);
在模板中:
<td *ngFor="let e of employees">{{e.name}}</td>
我试过的
我当然尝试了以下方法:
- ApplicationRef.tick()
- NgZone.run(回调)
- ChangeDetectorRef.detectChanges()
这些答案的解决方案都不适合我:
在 Angular 2 版本 6 中更新 MatTableDataSource 的正确方法
没有什么能解决我的问题。每次我使用路由器时,视图都会保持冻结状态。它已经到了我正在考虑使用window.location.reload()
如果没有其他方法的地步。
更新
我在评论中尝试了yehonatan yehezkel和MikeOne的建议。只要我不使用路由器,它们都可以工作。一旦我开始导航,视图就不再更新。所以这证实了共同点是这里的路由器。我错过了什么?为什么路由器阻止视图更新?
更新2
致 Gergő Éles评论:
问题可能来自我为嵌套模块声明路由的方式吗?
在app-routing.module
const routes: Routes = [
{
path: employees
canActivate: [CanActivateRoute],
loadChildren: () => import('./modules/employee/employee.module').then(mod => mod.EmployeeModule)
}
];
@NgModule({
imports: [
RouterModule.forRoot(routes),
...
],
exports: [RouterModule]
})
export class AppRoutingModule { }
并在employee.module
:
const routes: Routes = [
{
path: '',
children: [
{
path: '',
component: EmployeeListComponent
}
]
}
];
@NgModule({
imports: [
RouterModule.forChild(routes),
...
],
declarations: [
EmployeeListComponent,
...
]
})
export class EmployeeModule { }