简体   繁体   English

Angular 4 条件路由/组件

[英]Angular 4 conditional routing/components

UPDATE: See below更新:见下文

So I have an app where I have two different organisations, when a user is using the app I therefore want to load different components depending on which organisation he belongs to.所以我有一个应用程序,其中有两个不同的组织,当用户使用该应用程序时,我希望根据他所属的组织加载不同的组件。

Approach 1: Do a simple conditional in a routes file.方法一:在路由文件中做一个简单的条件语句。

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

This works, but ONLY on localhost, when I push to heroku and run in production the app just gives the wrong component.这有效,但仅在本地主机上,当我推送到 heroku 并在生产中运行时,应用程序只会提供错误的组件。 I've tried adding log outputs to this user-route.ts file, logs show up as expected on localhost but on production there is just nothing.我已经尝试将日志输出添加到这个 user-route.ts 文件中,日志在本地主机上按预期显示,但在生产中什么都没有。 "user" object from localStorage exist in both cases and are identical. localStorage 中的“user”对象在两种情况下都存在并且是相同的。 NOTE: this approach was also working fine with Angular 2, with Angular 4 something seems to happen with the routes file when running in production but who knows what.. maybe its compiled in some way that make the if conditional break.注意:这种方法也适用于 Angular 2,在 Angular 4 中,在生产中运行时路由文件似乎发生了一些事情,但谁知道是什么......也许它以某种方式编译,使 if 条件中断。

Approach 2. Use routes and guards.方法 2. 使用路线和守卫。 Add two guards for the different organisation.为不同的组织添加两个警卫。 Works but the routes has to be different.有效,但路线必须不同。 The code below doesn't work as the first empty route is always checked, but the second is not.下面的代码不起作用,因为第一个空路由总是被检查,但第二个不是。 I need the path to be empty ('').我需要路径为空('')。

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

Since every topic on guards and conditional routing seems to be about whether to show "home" or "login" I don't really know if there is a better way to use guards.由于关于守卫和条件路由的每个主题似乎都是关于是否显示“家”或“登录”,我真的不知道是否有更好的方式来使用守卫。 Ideally something like:理想情况下是这样的:

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

Approach 3. Use ngIf in parent template.方法 3. 在父模板中使用 ngIf。 This also works but I have to manually hide and show the component when moving further down the routes to "DetailsComponent"这也有效,但在进一步向下移动到“DetailsComponent”的路线时,我必须手动隐藏和显示组件

SO how do you do something so seemingly trivial as showing a different component based on a conditional?那么你如何做一些看似微不足道的事情,比如根据条件显示不同的组件?

UPDATE 1:更新1:

The closest, although not working, I got to my desired behaviour was using named router outlets.最接近的,虽然不起作用,但我达到了我想要的行为是使用命名的路由器插座。

The right components are loaded but only for the two top routes.加载了正确的组件,但仅适用于两条顶级路线。 The ones with an empty path.那些有空路径的。 For the the two routes with a id parameter I get对于带有 id 参数的两条路线,我得到

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

Which is weird because if I enter the url manually everything loads correctly:/ Called with:这很奇怪,因为如果我手动输入 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>

You could try the dynamic component loader.你可以试试动态组件加载器。

Details are in the Angular docs here: https://angular.io/guide/dynamic-component-loader详细信息在此处的 Angular 文档中: https : //angular.io/guide/dynamic-component-loader

Simply what about this?只是这个呢?

routing config:路由配置:

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

Toppage component:首页组件:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM