Условная маршрутизация Angular 4 / компоненты

ОБНОВЛЕНИЕ: см. ниже.

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

Подход 1. Выполните простое условное выражение в файле маршрутов.

import { Routes } from '@angular/router';

import { UserStartComponent } from './user-start.component';
import { UserDetailComponent } from './user-detail/user-detail.component';

import { mia_UserStartComponent } from './mia/mia_user-start.component';
import { mia_UserDetailComponent } from './mia/user-detail/mia_user-detail.component';

const user = JSON.parse(localStorage.getItem('MYW_CLOUD_USER_INFO'));

const startcomp = user && user.custom_fields.organization && user.custom_fields.organization.name_id === 'mia' ? mia_UserStartComponent : UserStartComponent;
const detailcomp = user && user.custom_fields.organization && user.custom_fields.organization.name_id === 'mia' ? mia_UserDetailComponent : UserDetailComponent;


export const USERS_ROUTES: Routes = [
  { path: '', component: startcomp },
  { path: ':id', component: detailcomp }
];

Это работает, но ТОЛЬКО на локальном хосте, когда я нажимаю на heroku и запускаю в продакшене, приложение просто выдает неправильный компонент. Я пробовал добавлять выходные данные журнала в этот файл user-route.ts, журналы отображаются, как и ожидалось, на локальном хосте, но на производстве их просто нет. "пользовательский" объект из localStorage существует в обоих случаях и идентичен. ПРИМЕЧАНИЕ. этот подход также отлично работал с Angular 2, с Angular 4 что-то происходит с файлом маршрутов при запуске в продакшене, но кто знает что ... возможно, он скомпилирован каким-то образом, что делает if условный перерыв.

Подход 2. Используйте маршруты и охрану. Добавьте двух охранников для другой организации. Работает, но маршруты должны быть другими. Приведенный ниже код не работает, поскольку первый пустой маршрут всегда проверяется, а второй - нет. Мне нужно, чтобы путь был пустым ('').

export const USERS_ROUTES: Routes = [
  { path: '', component: mia_UserStartComponent, canActivate: [OrganizationMiaGuard] },
  { path: '', component: UserStartComponent, canActivate: [OrganizationCelsiusGuard] }
  { path: ':id', component: detailcomp }
];

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

{ path: '', component: mia_UserStartComponent, canActivate: [OrganizationMiaGuard], **alternative**: UserStartComponent }

Подход 3. Используйте ngIf в родительском шаблоне. Это тоже работает, но мне приходится вручную скрывать и показывать компонент при движении дальше по маршрутам к «DetailsComponent».

Итак, как вы делаете что-то настолько, казалось бы, тривиальное, как показ другого компонента на основе условия?

ОБНОВЛЕНИЕ 1:

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

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

Error: Cannot match any routes. URL Segment: 'reports/1'

Это странно, потому что, если я ввожу URL-адрес вручную, все загружается правильно: / Вызывается с помощью:

<a [routerLink]="[userId]" ....

-

{ path: '', outlet: 'UserStartComponent', pathMatch: 'full', component: UserStartComponent },
{ path: '', outlet: 'mia_UserStartComponent', pathMatch: 'full', component: mia_UserStartComponent},

{ path: ':id', outlet: 'UserDetailComponent', pathMatch: 'full', component: UserDetailComponent },
{ path: ':id', outlet: 'mia_UserDetailComponent', pathMatch: 'full', component: mia_UserDetailComponent},

-

<router-outlet *ngIf="organization == 'celsius_golf'" name='UserStartComponent'></router-outlet>
<router-outlet *ngIf="organization == 'mia'" name='mia_UserStartComponent'></router-outlet>

<router-outlet *ngIf="organization == 'celsius_golf'" name='UserDetailComponent'></router-outlet>
<router-outlet *ngIf="organization == 'mia'" name='mia_UserDetailComponent'></router-outlet>

person Out of Orbit    schedule 19.06.2017    source источник
comment
как вы определяете, что пользователь из какой организации, я думаю, из некоторых параметров пути URL или параметров запроса. вы можете извлечь это значение при загрузке компонента, а затем загрузить или перенаправить приложение для загрузки компонентов, вы также можете изучить динамические компоненты, но я не думаю, что это предназначено для такой тривиальной вещи. Обязательно измените базовый href при развертывании на сервере   -  person Rahul Singh    schedule 20.06.2017
comment
Я получаю информацию о пользователе из localStorage. Может быть, мне просто лучше сделать разные маршруты для разных организаций, но кажется странным, что такая вещь может понадобиться.   -  person Out of Orbit    schedule 20.06.2017
comment
чтобы вы могли получить значение из локального хранилища в своей службе, а затем вызвать соответствующий маршрут из этого значения, это не работает?   -  person Rahul Singh    schedule 20.06.2017
comment
Да, я мог бы это сделать, но до сих пор у меня не было отдельных маршрутов. Это был тот же маршрут, но в моем файле маршрутов я назначил разные компоненты на основе условий. Что нормально работало в Angular 2, но не в Angular 4. Возможно, это неправильный подход: /   -  person Out of Orbit    schedule 20.06.2017
comment
да, мне также нужно решение для этого, в моем случае я хочу обрабатывать динамический поддомен   -  person chintan adatiya    schedule 08.11.2017


Ответы (2)


Вы можете попробовать загрузчик динамических компонентов.

Подробности в документации по Angular здесь: https://angular.io/guide/dynamic-component-loader

person DeborahK    schedule 19.06.2017
comment
Я предполагаю, что это сработает, но тогда мне все равно придется самостоятельно управлять множеством логики переключения компонентов в родительском компоненте. По сути, это будет то же самое, что использовать * ngIf и добавить правила, для какого компонента показывать, а не показывать. - person Out of Orbit; 20.06.2017

Просто что насчет этого?

конфигурация маршрутизации:

export const USERS_ROUTES: Routes = [
  { path: '', component: ToppageComponent },
  { path: ':id', component: detailcomp }
];

Компонент Toppage:

@Component({
    template: `
        <mia-user-start *ngIf="mia"></mia-user-start>
        <user-start *ngIf="!mia"></user-start>
    `
})
export class ToppageComponent implements OnInit {

    mia: boolean;

    ngOnInit() {
        const user = JSON.parse(localStorage.getItem('MYW_CLOUD_USER_INFO'));
        this.mia = user && user.custom_fields.organization && user.custom_fields.organization.name_id === 'mia';
    }
}
person ttskch    schedule 21.06.2018