Angular中queryParams订阅异常:点击编辑服务器功能失效排查
用户视角
点击“编辑服务器”按钮后,本该允许编辑服务器,但功能未正常生效,以下是问题截图:
(1)
(2)
开发者视角
我是Angular路由新手,现在订阅queryParams时拿到的是空对象,怀疑是导航代码有问题:
this.router.navigate(['edit', { queryParams: {allowEdit: this.server.id == 3 ? '1' : '0'}}], {relativeTo: this.route})
路由配置里已经把edit设为servers的孙路由,但EditComponent没加载,ngOnInit也没执行。相关代码片段如下:
App Module路由配置
// 相关路径配置 // 之前':id'和':id/edit'是同级,我改成了'edit'作为'servers'的孙路由,但EditComponent就是不加载,ngOnInit也没触发。 { path: 'servers', component: ServersComponent, children: [ { path: ':id', component: ServerComponent, children: [ { path: 'edit', component: EditServerComponent }, ] } ] },
Servers HTML模板
<div class="list-group"> <!-- Routerlink指向server组件而非'edit-server'组件 --> <a [routerLink] = "['/servers', server.id]" href="#" class="list-group-item" *ngFor="let server of servers"> {{ server.name }} </a> </div> <!-- 其他无关代码省略 --> <router-outlet></router-outlet>
Server HTML模板
<!-- display用来控制显示编辑组件还是服务器详情,这部分没问题 重点看按钮部分 --> <div [ngSwitch]="display"> <div *ngSwitchDefault> <h5>{{ server.name }}</h5> <p>Server status is {{ server.status }}</p> <button class="btn btn-primary" (click)="onEdit()">Edit Server</button></div> <div *ngSwitchCase="1"> <router-outlet></router-outlet> </div> </div>
Edit-Server TS代码
server: {id: number, name: string, status: string}; serverName = ''; serverStatus = ''; allowEdit: boolean id: number constructor(private serversService: ServersService, private route: ActivatedRoute) { } ngOnInit() { this.route.snapshot.queryParams this.route.snapshot.fragment // 已经导航到EditServerComponent,但params是空对象,所以allowEdit一直是false // 因为空对象不等于'1' this.route.queryParams.subscribe((params: Params) => { this.allowEdit = params['allowEdit'] == '1' ? true : false }) // 我80%确定下面这段代码和问题无关 this.route.params.subscribe((params: Params) => { this.id = +params['id'] }) this.server = this.serversService.getServer(this.id); this.serverName = this.server.name; this.serverStatus = this.server.status; } onUpdateServer() { this.serversService.updateServer(this.server.id, {name: this.serverName, status: this.serverStatus}); } }
Edit Server模板
<h4 *ngIf="!allowEdit">No editing the server!</h4> <div *ngIf="allowEdit"> <!-- 因为allowEdit一直是false,这部分代码永远不会执行 --> </div>
问题排查与解决方案
- 导航代码参数位置错误
你当前的navigate调用把queryParams放在了路由数组里,这会被解析为路由参数而非查询参数。正确写法是将queryParams作为第二个配置对象的属性:
this.router.navigate(['edit'], { queryParams: { allowEdit: this.server.id == 3 ? '1' : '0' }, relativeTo: this.route })
确保路由出口正常显示
检查onEdit()方法是否正确设置了display = 1——只有当display为1时,ServerComponent里的<router-outlet>才会显示,EditServerComponent才能被加载。如果display未切换,路由出口不显示,组件自然不会初始化,ngOnInit也不会执行。调整服务器数据获取时机
在EditServerComponent的ngOnInit中,你同步执行了服务器数据获取,但此时id可能还没从params订阅中拿到。建议把服务器数据获取移到params订阅的回调里:
this.route.params.subscribe((params: Params) => { this.id = +params['id']; this.server = this.serversService.getServer(this.id); this.serverName = this.server.name; this.serverStatus = this.server.status; });
- 路由配置验证
当前路由配置是正确的,edit作为:id的子路由,路径为servers/:id/edit,导航时用相对路径['edit']结合relativeTo: this.route(当前在ServerComponent,对应servers/:id)会正确生成目标路径。
内容的提问来源于stack exchange,提问作者Yousef
相关产品推荐
相关产品推荐

