我们假设我有3个网址:
/:projectId/info
,
/:projectId/users
,
/:projectId/users/:userId/profile
。所有人都有param projectId
。 UI有一个组件可以从一个项目切换到另一个项目。所以我需要:
所以我需要类似this.router.replaceParam(currentUrl, {projectId: 'project_id_2'})
的内容,它会将/project_id_1/users/user_id_1/profile
转换为/project_id_2/users/user_id_1/profile
(以及:projectId
param的任何其他网址
我认为这是一个简单而常见的问题,但在1小时内没有找到解决方案。建议的here解决方案无效,如上一条评论中所述
答案 0 :(得分:2)
您可以使用HTML或Ts
1>在HTML中
[routerLink]="['../info']"
Or
[routerLink]="['../users']"
like this etc....
2>在Typescript
中
this.router.navigate(['../users'], { relativeTo: this.activatedRoute });
答案 1 :(得分:2)
要从当前网址导航到特定链接,您可以执行以下操作
constructor(private route: ActivatedRoute, private router: Router){}
ngOnInit() {
this.route.params.subscribe(params => {
// PARAMS CHANGED ..
let id = params['projectid'];
});
}
navigate(){
this.router.navigateByUrl(this.router.url.replace(id, newProjectId));
// replace parameter of navigateByUrl function to your required url
}
在ngOnInit函数中,我们订阅了params,因此我们可以观察并执行url参数中任何更改的语句。
答案 2 :(得分:0)
查看您的问题,您想要更改2个参数。
如下所述:
https://angular.io/api/router/Router#navigatebyurl
您可以实施router.navigate([yourprojectId, 'users', youruserId , 'profile'], {relativeTo: route});
答案 3 :(得分:0)
这会有帮助吗?
export class MyComponent {
constructor(private router: Router, private route: ActivatedRoute){}
public navigate(){
const projectId = getNewProjectId(route.snapshot.params['projectId']);
this.router.navigate([
projectId,
this.router.url.substring(this.router.url.indexOf('/') + 1, this.router.url.length)
]);
}
}
如果您需要更精细的控制(基本上,您不知道当前URL应该是什么样子),请尝试遍历路由树,处理路由配置路径。您可以在其中找到:projectId
配置,并根据您在树中的位置,了解您的router.url
结构。
let route = activatedRoute.snapshot;
while (route) {
if (route.routeConfig && route.routeConfig.path) {
// Do something with the path
}
route = route.parent;
}
希望这有点帮助: - )
答案 4 :(得分:0)
这是你可以做到的一种方式。获取网址,获取当前的参数(因为它听起来你不知道它们是什么),如果你同时拥有projectid和userid,那么你将路由到两者。如果网址以#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
int main() {
char* c;
scanf(" %c", c);
printf("%c\n", *c);
return 0;
}
结尾,那么您就在'o'
路线上,如果它以/info
结尾,那么它就是's'
路线。
/users
这假设你不知道你在哪条路线上,但在所有现实中你应该知道你是否在用户,信息或个人资料中。否则,您将一个组件用于三个截然不同的页面。
答案 5 :(得分:0)
在相应的组件中(即.ts文件中),您需要添加
import { Subscription } from 'rxjs/Subscription';
使用
进入你的@componentmyVariable: {projectId: string, userId: string};
paramsSubscription: Subscription;
ngOnInit(){
this.myVariable = {
projectId: this.route.snapshot.params['projectId'],
// userId: this.route.snapshot.params['userId']
};
this.paramsSubscription = this.route.params
.subscribe(
(params: Params) => {
this.myVariable.projectId = params['projectId'];
// this.myVariable.userId = params['userId'];
}
);
}
以及您有兴趣更改现有route.let的方法,假设您想要从以下方法更改路线
changeRoute(): void{
this.router.navigate(['/curentUrl',this.project_id_2, 'users/user_id_1/profile']);
}
希望这可以帮助你
答案 6 :(得分:0)
您可以使用:
this.router.navigate(
[],
{
relativeTo: this.activatedRoute,
queryParams: {projectId: 'project_id_2'},
queryParamsHandling: "merge", // remove to replace all query params by provided
});
答案 7 :(得分:0)
由于我还花了几个小时研究这个问题,所以我也想分享我的解决方案。
我在路由中添加了一个自定义数据项,该数据项应能够在accountNames(您的情况下为projectIds)之间进行切换:
const routes: Routes = [
{
path: 'expenses/:accountName',
component: ExpenseListComponent,
data: { changeAccountUrl: ['expenses', ':accountName'] },
}
];
这样,任何组件都可以很容易地检查ActivatedRoute的数据是否存在该项目。如果存在,则可以使用它生成一条路线。
另一个好处是您可以更好地控制生成的路线。
答案 8 :(得分:0)
使用Angular 7,我通过使用在每个NavigationEnd
上存储路由器当前状态的服务来实现这一点。然后,我可以遍历状态树并构造一个路径数组,以后可用于查找和替换:projectId
之类的参数。
获取路径数组:
constructor(private router: Router) {
this.router.events.subscribe(event => {
if (event instanceof NavigationEnd) {
this.pathArray = this.getPathArray(this.router.routerState.snapshot.root);
}
}
}
getPathArray(route: ActivatedRouteSnapshot) {
let array = [];
if (route.routeConfig && route.routeConfig.path !== '') {
array.push(route.routeConfig.path);
}
if (route.firstChild) {
array = array.concat(this.getPathArray(route.firstChild));
}
return array;
}
替换:projectId
:
replacePathArrayId(id) {
return this.pathArray.map(path => {
return path.replace(':projectId', id);
})
}
并使用router.navigate(service.replacePathArrayId(id))
实际更改路线。
答案 9 :(得分:0)
我今天面对角度9的问题。 就我而言,我遇到了树形网址情形:
something/i-ignore/../my-path
我在其中显示预定义值(例如:最新值)something/i-ignore/../my-path
-> something/i-ignore/../my-path/1
我明确要求从基本网址开始的/1
资源something/i-ignore/../my-path/1
-> something/i-ignore/../my-path/2
我在哪里更改请求的资源一种有趣的方法是proposed by Omkar Jadhav,他以编程方式从ActivatedRoute向后退了一步
this.router.navigate(['../users'], { relativeTo: this.activatedRoute });
我对参数更改事件做出了反应,使用了code proposed by Michael
的简化版本this._route.params
.subscribe((params) => {
console.log(params) // prints {resourceId: "1"}
});
结合以上所述,我可以开始处理案例2和案例3。
const url = this.router.url.split('my-path');
if (url[1] && 0 < url[1].length) {
this.router.navigate(['../' + this.newResourceId],{relativeTo: this.activatedRoute});
} else {
this.router.navigate([this.newResourceId], {relativeTo: this.activatedRoute});
}
然后我只需要订阅参数
this.activatedRoute.params.subscribe(params => this.getResource(params['resourceId']));
完整代码:
ngOnInit(): void {
this.activatedRoute.params.subscribe(params => this.getResource(params['resourceId']));
this.getResource(this.activatedRoute.snapshot.params?.resourceId);
}
resourceRequestEvent(resourceId: number) {
// this will trigger the page refresh
const url = this.router.url.split('my-path');
if (url[1] && 0 < url[1].length) {
this.router.navigate(['../' + resourceId], {relativeTo: this.activatedRoute});
} else {
this.router.navigate([resourceId], {relativeTo: this.activatedRoute});
}
}
答案 10 :(得分:0)
此服务将使用当前路由配置重建当前网址。它的工作原理是重建网址段,并用参数中的匹配键替换以:
开头的段
要更新当前网址,您只需调用方法
this.routingService.updateRoute({id: 123})
import { Injectable } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Params, Router } from '@angular/router';
import { Subject } from 'rxjs';
import { filter } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class RoutingService {
routeChange: Subject<void> = new Subject<void>();
params: Params;
constructor(
private router: Router,
private activatedRoute: ActivatedRoute
) {
this.router.events
.pipe(filter(event => event instanceof NavigationEnd))
.subscribe(() => {
this.params = this.activatedRoute.firstChild.snapshot.params;
this.routeChange.next();
});
}
updateRoute(data: { [key: string]: string | number }) {
const params = { ... this.params, ...data };
const segments = this.activatedRoute.firstChild.snapshot.routeConfig.path.split('/');
const commands = segments.map(v => v.indexOf(':') === 0 ? params[v.substr(1)] : v);
if (commands.join('/') !== this.activatedRoute.firstChild.snapshot.url.join()) {
return this.router.navigate(commands);
}
}
}
答案 11 :(得分:0)
这将采用一个 url 字符串并更新 params 对象中的所有参数:
constructor(private route: ActivatedRoute, private router: Router){}
setRouteParams(url: string, route: ActivatedRoute, params: any): string {
for (const p in params) {
const old = route.snapshot.paramMap.get(p);
url = url.replace(`/${old}/`, `/${params[p]}/`);
}
return url;
}
它遍历 params
的属性,从当前路由中获取每个属性 p
的当前值,然后将其替换为属性 params[p]
的值。我们想知道当前的路由参数值,以便我们知道需要替换什么。匹配 /${old}/
而不是 old
将避免在 /aa/
中想用 /bb/
替换 /aad/aa/
而得到 /bbd/aa/
的情况。
可以这样调用setRouteParams('/project_id_1/users/user_id_1/profile', this.activatedRoute, {projectId: 'project_id_2')
。
这不会处理像 /11/users/11/profile/
和 params
{userId: '22'}
这样的路由。它将代替 projectId
。为了处理这种情况,我们需要知道参数 {userId: {value: '22', position: 3}}
的顺序(基于 1 的位置,因为下面的第一段将是空字符串)。
setRouteParams(url: string, params: any): string {
const segments = url.split('/');
for (const p in params) {
segments[params[p].position] = params[p].value;
}
return segments.join('/');
}
如果你想同时导航:
setRouteParamsAndNavigate(router: Router, params: any): void {
const segments = router.url.split('/');
for (const p in params) {
segments[params[p].position] = params[p].value;
}
router.navigateByUrl(segments.join('/')).then(() => {});
}
答案 12 :(得分:0)
为了让@khush 的回答更加完整并解决需要 id
唯一的问题,我做了以下调整:
id: string;
constructor(private route: ActivatedRoute, private router: Router) {}
ngOnInit() {
this.route.params.subscribe(params => {
this.id = params['id'];
});
}
navigate() {
this.router.navigateByUrl(this.router.url.replace(`/${this.id}/`, `/${newId}/`));
}