typescript - Angular 4 villkorlig routing/komponenter


UPPDATERING: Se nedan

Så jag har en app där jag har två olika organisationer, när en användare använder appen vill jag därför ladda olika komponenter beroende på vilken organisation han tillhör.

Metod 1: Gör en enkel villkorssats i en ruttfil.

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

Detta fungerar, men ENDAST på localhost. När jag pushar till Heroku och kör i produktion visar appen bara fel komponent. Jag har försökt lägga till loggutgångar till den här user-route.ts-filen, loggarna dyker upp som förväntat på localhost men i produktion finns det bara ingenting. "user"-objektet från localStorage finns i båda fallen och är identiska. NOTERA: detta tillvägagångssätt fungerade även bra med Angular 2, med Angular 4 verkar något hända med routes-filen när den körs i produktion, men vem vet vad… kanske kompileras den på ett sätt som gör att if-satsen bryts.

Tillvägagångssätt 2. Använd rutter och vakter. Lägg till två vakter för den olika organisationen. Fungerar men rutterna måste vara olika. Koden nedan fungerar inte eftersom den första tomma rutten alltid kontrolleras, men den andra inte gör det. Jag behöver att vägen ska vara tom ('').

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

Eftersom varje ämne om guards och villkorsstyrd routing verkar handla om huruvida man ska visa "home" eller "login" vet jag egentligen inte om det finns ett bättre sätt att använda guards. Helst något i stil med:

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

Tillvägagångssätt 3. Använd ngIf i föräldratemplet. Detta fungerar också men jag måste manuellt dölja och visa komponenten när jag går vidare ner i rutterna till "DetailsComponent"

Så hur gör man något så till synes trivialt som att visa en annan komponent baserat på ett villkor?

UPPDATERING 1:

Det närmaste, även om det inte fungerade, jag kom till mitt önskade beteende var att använda namngivna routeruttag.

De rätta komponenterna är laddade men endast för de två översta rutterna. De med en tom väg. För de två rutterna med en id-parameter får jag

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

Vilket är konstigt eftersom om jag skriver in url:en manuellt laddas allt korrekt:/ Anropad med:

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

Svar #1

Bara vad sägs om detta?

routningskonfiguration:

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

Toppkomponent:

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

Svar #2

Du kan prova den dynamiska komponentladdaren.

Detaljer finns i Angular-dokumentationen här: https://angular.io/guide/dynamic-component-loader

Relaterade artiklar