Угловой роутер: как заменить парам? - PullRequest
0 голосов
/ 10 июня 2018

Предположим, у меня есть 3 URL: /:projectId/info, /:projectId/users, /:projectId/users/:userId/profile.Все они имеют параметр 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 час.Предлагаемое здесь решение не работает, как отмечено в последнем комментарии

Ответы [ 9 ]

0 голосов
/ 12 апреля 2019

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

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

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

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

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

0 голосов
/ 08 августа 2019

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

0 голосов
/ 19 июня 2018

В соответствующем компоненте (т. Е. В файле .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']);
}

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

0 голосов
/ 21 марта 2019

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

this.router.navigate(
      [],
      {
        relativeTo: this.activatedRoute,
        queryParams: {projectId: 'project_id_2'},
        queryParamsHandling: "merge", // remove to replace all query params by provided
      });
0 голосов
/ 19 июня 2018

Чтобы перейти к конкретной ссылке из текущего 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-адреса.параметр.

0 голосов
/ 18 июня 2018

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

1> В HTML

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

2> В машинописном тексте

this.router.navigate(['../users'], { relativeTo: this.activatedRoute });
0 голосов
/ 15 июня 2018

Это один из способов сделать это.Получите URL-адрес, получите текущие параметры (потому что звучит так, будто вы не знаете, что они есть), если у вас есть и projectid, и идентификатор пользователя, то вы направляетесь к одному с обоими.Если 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});
       }
  });
}

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

0 голосов
/ 14 июня 2018

Поможет ли это?

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

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

0 голосов
/ 13 июня 2018

Глядя на ваш вопрос, вы хотите изменить 2 параметра.

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

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

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

...