Angular 4中paramMap的subscribe在使用子路由时无效

4
在我们的Angular 4应用中,我们有一个下拉列表,其中包含合同列表。
一旦用户选择了合同,我们就会触发router.navigate,将选定的contractId更改为url,并进行http请求
实际上,这很简单: this.activatedRoute.paramMap.subscribe(...使用contractId进行请求...) 这对于平面路由非常有效。
但是在子路由中,它无法工作,例如对于此路由:
export const customerRoutes: Routes = [
{
    path: ":contractId/Customers",
    component: CustomersComponent,
    children: [
        { path: "", redirectTo: "Children", pathMatch: "full" },
        { path: "Children", component: ChildrenComponent }
    ]
  }
];

上面的路由给了我以下URL: http://localhost:4033/20917/Customers/Children 现在假设我想在下拉列表中选择一个新合同...
...这是下拉列表的onChange事件:
public onChange(contract: Contract): void {
  this.router.navigate([contract.id, window.location.pathname.split("/")[3]]);
}

当我使用window.location.pathname.split("/")[3]时,返回结果为:Customers

但是,URL已更改为http://localhost:4033/33444/Customers/Children,但订阅并未被触发。为什么?


这段代码 this.activatedRoute.paramMap.subscribe(...request with contractId...) 在哪里?它只会捕捉与组件相关的路由更改。因此,要捕捉到 Children 路由的更改,这段代码需要在 Children 组件中。那么它是在那里吗? - DeborahK
感谢@DeborahK - 是的,就在那里 - 订阅者在子组件中。使用plunker应该很容易重现这个问题。我会试一试... - DAG
我已经解决了@DeborahK提出的问题,这个问题非常有趣。我在网上没有看到太多相关内容。我还尝试了Pluralsight课程,但那里没有涉及到这个问题。当你在子组件中想要通过订阅来访问父组件的参数时,需要使用:this.activatedRoute.parent.paramMap... 然后它就可以工作了。我会发布一个带有指向plunker的链接的答案。 - DAG
1
很高兴你解决了问题。在我的Pluralsight的Angular Routing课程中,我确实讨论了激活路由的.parent属性,但是与观察数据属性有关。这在概念上是类似的。 - DeborahK
2个回答

4

要监听父组件的变化事件,我们需要显式调用:

this.activatedRoute.parent.paramMap.subscribe(... 使用 contractId 的请求...)

这并没有在文档中提到,我已经为此创建了一个请求:https://github.com/angular/angular/issues/18862


1
看起来你关闭了这个问题..我可以问一下原因吗?我现在也有类似的问题,但仍然没有找到解决方法.. - Mackelito
1
这是一份关于文档和功能的请求,而不是一个问题。解决方案已经给出。 - DAG
@DAG,你能演示一下如何使用pipe()运算符吗?自从Angular 6以后,你不能再使用.map了。我试着像在plunkr中那样重新创建它,代码如下:this.activatedRoute.parent.paramMap.pipe( map(m => m.get("contractId")), distinctUntilChanged((previous: any, current: any) => {return true})).subscribe(),但是它没有起作用。 - Maurice

0
对我来说,既不是activatedRoute.parent.parentMap也不是activatedRoute.parentMap有效。经过一些尝试和错误,我想出了以下解决方案:
const params$ = router.events
    .pipe(map(() => _.assign({}, activatedRoute.snapshot.params, activatedRoute.firstChild?.snapshot.params)));

这最终向我展示了所有参数。显然应该进行防抖处理,因为路由器会发出很多事件,但这是我能找到的最好的方法。

我正在使用 Angular 11。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接