Можно ли собрать все параметры из ActivatedRoute в angular?

Я создаю приложение angular 4. Бывает, что мне нужно получить параметры из моего URL-адреса, которые находятся на разных уровнях глубины, что приводит к тому, что способ получения моих параметров неодинаков.

Предположим, у нас есть этот URL:

https://mysite/companies/:companyID/cups/:cupId/drawings/:drawId

Обычно, согласно документам angular, нам нужно было бы сделать что-то вроде:

ngOnInit() {
this.activatedRoute.parent.parent.params.subscribe((params: Params) => 
{this.companyId = params['companyId'];
});
this.activatedRoute.parent.params.subscribe((params: Params) => 
{this.cupId = params['cupId'];
});
this.activatedRoute.params.subscribe((params: Params) => 
{this.drawId = params['drawId'];
});
}

Обратите внимание, что это с учетом того, что мы находимся внутри DrawDetailComponent, что означает, что мы находимся в компоненте, который является последним дочерним элементом в этой иерархии.

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

Итак, возможно ли получить все параметры из ваших URL-адресов с одним и тем же вызовом?

Что-то типа:

this.activatedRoute.parent.parent.params.subscribe((params: Params) => 
    {this.companyId = params['companyId'];
    {this.cupId = params['cupId'];
    {this.drawId = params['drawId'];
});

Мы хотели бы иметь единый, не зависящий от глубины способ получения всех параметров из нашего URL.

На самом деле мы также пробовали что-то вроде:

const property = 'companyId';
this.activatedRoute.pathFromRoot.forEach((item) => {
  if (item.snapshot.params.hasOwnProperty(property)) {
    item.params.subscribe((params: ParamMap) => {
      this.companyId = params[property];
    });
  }
});

Но мы надеемся найти лучший, более общий и проверяемый способ.

Обычно в таких средах, как Django, разработчик может собрать всю необходимую информацию из URL-адреса за один шаг. Это нормально иметь подписки для автоматической обработки изменений этих параметров в случае Angular, но ИМХО это далеко не удобно и не тестируемо.


person pinkfloyd    schedule 26.07.2017    source источник
comment
Итерация по родителям — это все, что вы можете здесь сделать. Вы боретесь с фреймворком, роутер не должен так использоваться. Angular — это не Джанго. Разработчики извлекли тяжелый урок из маршрутизатора A1. Маршрутизатор A4 был спроектирован как модульный, считайте это особым случаем инкапсуляции. Дочерние маршруты не должны знать о родителях и получать все необходимое через data, собственные параметры и общих провайдеров. Вероятно, у вас есть проблема XY с дизайном приложения, которую предполагается решить другим способом.   -  person Estus Flask    schedule 26.07.2017
comment
Спасибо, интересный ответ, он указывает мне в другом направлении, возможно, более подходящем. Не могли бы вы поделиться некоторыми ссылками, описывающими эту упомянутую проблему XY? С другой стороны, предположим, что у нас есть 4 компонента, A, B, C, D, каждый из которых вложен в предыдущий: A -> B -> C -> D, и вам нужно в C, чтобы данные поступали из 3 родительские компоненты. Следует ли правильно делиться этими данными с помощью @Inputs внутри каждого из компонентов? Компонент D в конечном итоге будет иметь 3 входа, только чтобы иметь доступ к простым параметрам, поступающим от родителей.   -  person pinkfloyd    schedule 26.07.2017


Ответы (1)


Я думаю, что вы должны сделать что-то вроде этого:

this.activatedRoute.params.subscribe(params => {
    this.companyId = params['companyId'];
    this.cupId = params['cupId'];
    this.drawId = params['drawId'];
});

Мне повезло с чем-то подобным в моих приложениях. Заметьте, я не подхожу к родителю. Активированный маршрут должен иметь все, что вам нужно.

Надеюсь это поможет!

person R. Richards    schedule 26.07.2017
comment
Я согласен. Я говорю это, зная, что есть исключения. Но я всегда немного съеживаюсь, когда людям нужна свободная функциональность маршрутизации. Определенно есть варианты использования динамической маршрутизации, но их не слишком много, когда вы вкладываете динамические поверх динамических. Из всего приложения ваша маршрутизация должна быть наиболее предсказуемой и последовательной с точки зрения работы в соответствии с проектом. - person joshrathke; 26.07.2017
comment
@Р. Ричардс, это не работает для нас. Обратите внимание, что здесь есть вложенные маршруты. Допустим, у вас есть модуль, в данном случае CompanyModule, у которого есть дочерний модуль: CupModule, каждый из которых имеет свою собственную маршрутизацию. Когда вы запрашиваете активированный маршрут внутри любого компонента в CupModule, он не знает о маршрутах родительского модуля. Вот почему в примере у нас есть 3 разных уровня вложенных запросов .parent, в зависимости от глубины. - person pinkfloyd; 26.07.2017
comment
@joshrathke, обычно в таких фреймворках, как Django, я просто получаю все параметры в любое время, когда это необходимо, с помощью одного простого вызова. Я думаю, что это не совсем зрелая функция в Angular. Возможно, получив ответы на этот вопрос, я изменю свое мнение :) - person pinkfloyd; 26.07.2017