Подтвердить что ты не робот

Угловой маршрутизатор: как заменить параметр?

Предположим, у меня есть 3 URL: /:projectId/info, /:projectId/users, /:projectId/users/:userId/profile. Все они имеют param projectId. Пользовательский интерфейс имеет компонент для переключения с одного проекта на другой. Так что мне нужно:

  1. Получить текущий URL
  2. Изменить параметр по имени (например, projectId)
  3. Перейдите на новый URL

Поэтому мне нужно что-то вроде this.router.replaceParam(currentUrl, {projectId: 'project_id_2'}) которое преобразует /project_id_1/users/user_id_1/profile в /project_id_2/users/user_id_1/profile (и любой другой URL-адрес с :projectId param )

Я думал, что это простая и распространенная проблема, но не нашел решения за 1 час. Предлагаемое здесь решение не работает, как отмечено в последнем комментарии

4b9b3361

Ответ 1

Чтобы перейти к определенной ссылке из текущего URL-адреса, вы можете сделать что-то вроде этого,

 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

Вы можете использовать либо HTML Or Ts

1> В HTML

[routerLink]="['../info']"
        Or
[routerLink]="['../users']"
    like this etc....

Ответ 3

Рассматривая свой вопрос, вы хотите изменить 2 параметра.

Как указано в:

https://angular.io/api/router/Router#navigatebyurl

Вы можете реализовать router.navigate([yourprojectId, 'users', youruserId, 'profile'], {relativeTo: route});

Ответ 4

Это поможет?

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;
}

Надеюсь, это немного поможет :-)

Ответ 5

Это один из способов сделать это. Получите url, получите текущие параметры (потому что это звучит так, как будто вы не знаете, что это такое), если у вас есть как projectid, так и userid, тогда вы направляетесь к одному из них. Если URL-адрес заканчивается на 'o' то вы находитесь на маршруте /info и если он заканчивается на 's' это маршрут /users.

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});
       }
  });
}

Предполагается, что вы не знаете, на каком маршруте вы находитесь, но во всей реальности вы должны иметь представление о том, что вы находитесь в пользователях, информации или профиле. В противном случае вы используете один компонент для трех разных страниц.

Ответ 6

В соответствующем компоненте (т.е. В файле.ts) вам нужно добавить

import { Subscription } from 'rxjs/Subscription';

Uder в ваш @component использовать следующие

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'];
    }
  );
}

и по какому методу вы заинтересованы в изменении существующего маршрута. Скажите, что вы хотите изменить маршрут из следующих методов

changeRoute(): void{
   this.router.navigate(['/curentUrl',this.project_id_2, 'users/user_id_1/profile']);
}

надеюсь, это может помочь вам

Ответ 7

Ты можешь использовать:

this.router.navigate(
      [],
      {
        relativeTo: this.activatedRoute,
        queryParams: {projectId: 'project_id_2'},
        queryParamsHandling: "merge", // remove to replace all query params by provided
      });

Ответ 8

Поскольку я также потратил часы на изучение этого вопроса, я также хочу поделиться своим решением.

Я добавил пользовательский элемент данных в маршруты, которые должны иметь возможность переключаться между accountNames (projectIds в вашем случае):

const routes: Routes = [
 {
   path: 'expenses/:accountName',
   component: ExpenseListComponent,
   data: { changeAccountUrl: ['expenses', ':accountName'] },
 }
];

Таким образом, любой компонент может легко проверить данные activRoute на наличие этого элемента. Если он присутствует, вы можете создать маршрут с ним.

Еще одним преимуществом является то, что вы имеете больше контроля над сгенерированными маршрутами.

Ответ 9

Используя 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)), чтобы фактически изменить маршрут.