问题
尝试从http://localhost:4200/#/place/(popup:tabs-modal)
导航
(插座)至http://localhost:4200/#/place/someId
请注意,该商店基本上是通往"地点"的儿童路线。
我能做什么
我可以关闭插座,然后结束:http://localhost:4200/#/place
:this.router.navigate(['place', { outlets: { popup: null } }]);
那么它很容易吗?
this.router.navigate(['place', 'someId', { outlets: { popup: null } }]);
然后应该导航到http://localhost:4200/#/place/someId
对吗?
错误。路由器为我生成一条非感性路线:"/place/(someId//popup:tabs-modal)"
我做错了吗?还是只是马车?
答案 0 :(得分:2)
this.router.navigate(['/', 'place', { outlets: { popup: null } }]);
您需要从根路径
领导编辑:
角度路由器有一个突出的问题,希望通过此拉取请求修复:https://github.com/angular/angular/pull/22394
与空路由器插座有关的问题。您还需要知道相对路径仅相对于路由器树(ActiveRoutes)而不是URL。考虑到这一点,我创建了一个辅助函数来解决问题,直到它在Angular 6中修复。
import { Router, ActivatedRoute } from '@angular/router';
/**
*
* Angular Relative path tempory solution. Angular doesn't like empty paths.
* Should be fixed in version 6 Pull request 22394
* https://github.com/angular/angular/pull/22394
*
* Angular Issue: https://github.com/angular/angular/issues/13011#issuecomment-274414952
*
* Before removing check relative paths work on named outlet. Using Navigate on named
* outlet currently relates to secondary routes (outlet:'route/test)
* this meant breaking out wasn't possiable using ../../ like documented in
* angular own documentation
*
* key Information: This is relative to routes like anuglar intended NOT URL path
*
* Bug only relates to going to parent and down the tree
*
* @export NavigateByRelative
* @param {string} path
* @param {Router} router
* @param {ActivatedRoute} route
*
*/
export function NavigateByRelative(path: string, router: Router, route: ActivatedRoute) {
/**
* Relative paths should always start with '../' as per angular documentation
* https://angular.io/guide/router#relative-navigation
*/
if (path.startsWith('../')) {
// split path into multiple paths
const paths = path.split('/');
// minus 1 on length as we gurantee need the last index
const totalPathToLastIndex = paths.length - 1;
// current index so we can start at this later on
let currentPathIndex;
// Relative to is so we get to the correct parent
let relativeTo = route;
// Check their is a parent and the current path still intended to go back up the tree
for (currentPathIndex = 0;
currentPathIndex < totalPathToLastIndex
&& relativeTo.parent !== undefined
&& paths[currentPathIndex] === '..';
currentPathIndex++
) {
relativeTo = relativeTo.parent;
}
// Navigate starting at the the currentpathIndex and relative to the current parent
router.navigate([...paths.splice(currentPathIndex )], { relativeTo });
} else {
// else use navigation as normal as this should work correctly
router.navigate([path]);
}
}
更新:23/10/2018 抱歉耽搁了。从角度6开始,路由器导航问题现已解决
更新:02/04/2019 Angular 7+再次引入了这个bug。
答案 1 :(得分:1)
我放弃了尝试让.navigate()
工作,最后使用了router.navigateByUrl('/place/someId')
。一个简单的解决方案让我望而却步。
答案 2 :(得分:0)
可接受的答案是一种不好的做法,因为您肯定不想在要关闭弹出窗口或任何其他操作时浏览NavigationByUrl。最好的办法是在路由器中执行以下操作:
{
path: 'place/:someid',
component: PlacePageComponent,
resolve: {someid: SomeIDResolver},
children: [
{
path: 'tabs-modal/:maybenextidhere',
outlet: 'popup',
component: TabsModalComponent,
resolve: {maybenextidhere: MaybeNextIDResolver},
},
]
},
然后是诀窍。在您要关闭弹出窗口的函数中,您想要调用如下代码:
this.router.navigate(['./', {outlets: { popup: null}}], {relativeTo: this.route.firstChild.firstChild});
答案 3 :(得分:0)
我遇到了同样的问题。问题是我希望能够在任何深度使用我的组件。因此,https://stackoverflow.com/a/50976238/1617590解决方案使我创建了一种稍微不同且更灵活的方法。
Helper方法将遍历主ActivatedRoute
并返回ActivatedRoute
属性所需的relativeTo
,以正确地导航到辅助出口。
private getRelativeTo(
obj: ActivatedRoute,
callback: (lastFirstChild: ActivatedRoute) => void
) {
Object.keys(obj).forEach((key) => {
if (key === 'outlet') {
if (obj[key] === PRIMARY_OUTLET) {
const fChild = obj.firstChild;
const nextFChild = fChild ? fChild!.firstChild : undefined;
if (fChild && nextFChild) {
nextFChild.outlet === 'modal' // name of your secondary outlet
? callback(fChild) // found child component with named outlet
: this.getRelativeTo(fChild, callback) // not found, go deeper
} else {
// No named child outlet found so just return back.
callback(this.route);
}
} else {
// First child is not the primary, so just return back.
callback(this.route);
}
}
});
}
这就是我用来关闭模态的方法:
...
constructor(
private router: Router,
private route: ActivatedRoute
) {}
closeModal() {
this.getRelativeTo(this.route, (lastFirstChild) => {
this.router.navigate(['./', { outlets: { modal: null } }], {
replaceUrl: true,
relativeTo: lastFirstChild,
});
});
}
这种方法可帮助我在与主插座相同的级别上以及用作子组件时,正确地从带有命名辅助插座的子路线中导航出来。
希望有帮助。