问题
Let's suppose I've got 3 urls:
/:projectId/info
,
/:projectId/users
,
/:projectId/users/:userId/profile
. All of them have param projectId
. UI has a component to switch from one project to another. So I need:
- Get current URL
- Change param by name (e.g. projectId)
- Navigate to new url
So I need something like this.router.replaceParam(currentUrl, {projectId: 'project_id_2'})
which will transform /project_id_1/users/user_id_1/profile
into /project_id_2/users/user_id_1/profile
(and any other URL with :projectId
param)
I thought it's a simple and common problem but didn't find a solution in 1 hour. Suggested here solution doesn't work as noted in the last comment
回答1:
To navigate to particular link from current url, you can do something like this,
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
}
On ngOnInit function, we have subscribed to params so we can observe and executes our statements on any change in url parameter.
回答2:
You can use either HTML Or Ts
1 > In HTML
[routerLink]="['../info']"
Or
[routerLink]="['../users']"
like this etc....
2 > In Typescript
this.router.navigate(['../users'], { relativeTo: this.activatedRoute });
回答3:
Looking at your question , you want to change the 2 parameters .
As stated in :
https://angular.io/api/router/Router#navigatebyurl
You can implement router.navigate([yourprojectId, 'users', youruserId , 'profile'], {relativeTo: route});
回答4:
Would this help?
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)
]);
}
}
In case you need more granular control (basically, you have no clue what the current URL should look like), try traversing the route tree, processing the route config paths. You can find the :projectId
configuration in there and based on where you are in the tree, you can understand your router.url
structure.
let route = activatedRoute.snapshot;
while (route) {
if (route.routeConfig && route.routeConfig.path) {
// Do something with the path
}
route = route.parent;
}
Hope this helps a little :-)
回答5:
This is one way you can do it. Get the url, get the current params (because it sounds like you don't know what they are), if you have both projectid and userid then you route to the one with both. If the url ends in 'o'
then you are on the /info
route and if it ends in 's'
then it is the /users
route.
constructor(private activatedRoute: ActivatedRoute) {}
replacePrarm(projectId) {
// get current url
const url = this.router.url;
// get current params
this.activatedRoute.params.subscribe((params: Params) => {
if(params['projectId'] && params['userId']) {
router.navigate(projectId, 'users', params['userId'], 'profile'], {relativeTo: route});
} else if (url[url.length - 1] === 'o') {
router.navigate(projectId, 'info'], {relativeTo: route});
} else if (url[url.length - 1] === 's') {
router.navigate(projectId, 'users'], {relativeTo: route});
}
});
}
This is assuming you have no idea what route you are on, but in all reality you should have some idea if you are in users, info, or the profile. Otherwise you're using one component for three very different pages.
回答6:
In the corresponding component(i.e in .ts file) you need to add
import { Subscription } from 'rxjs/Subscription';
Uder into your @component use following
myVariable: {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'];
}
);
}
and on which method you are interested to change existing route.let's say you want to change route from following methods
changeRoute(): void{
this.router.navigate(['/curentUrl',this.project_id_2, 'users/user_id_1/profile']);
}
hope this may helps you
回答7:
You can use:
this.router.navigate(
[],
{
relativeTo: this.activatedRoute,
queryParams: {projectId: 'project_id_2'},
queryParamsHandling: "merge", // remove to replace all query params by provided
});
回答8:
Since I also spent hours in investigating this question, I also want to share my solution.
I added a custom data item to the routes that should be able to switch between accountNames (projectIds in your case):
const routes: Routes = [
{
path: 'expenses/:accountName',
component: ExpenseListComponent,
data: { changeAccountUrl: ['expenses', ':accountName'] },
}
];
This way it's easy for any component to check the activatedRoute's data for the presence of that item. If it's present, you can generate a route with it.
One more benefit is that you have more control about the generated routes.
回答9:
Using Angular 7, I achieved this by using a service that stores the current state of the router on every NavigationEnd
. I can then traverse the state tree and construct an array of paths that can be used later to find and replace a param like :projectId
.
Getting path array:
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;
}
Replacing :projectId
:
replacePathArrayId(id) {
return this.pathArray.map(path => {
return path.replace(':projectId', id);
})
}
And using router.navigate(service.replacePathArrayId(id))
to actually change the route.
来源:https://stackoverflow.com/questions/50784299/angular-router-how-to-replace-param