我想将一个组件异步附加到一个路由,给出一个条件。
以下示例(可以是异步的)根据用户角色加载一个或另一个组件:
import { UserDashboardComponent } from './user-dashboard.component'
import { AdminDashboardComponent } from './admin-dashboard.component'
const role = 'admin' // Just for the example
const comp = role === 'admin' ? AdminDashboardComponent : UserDashboardComponent
const routes: Routes = [
{ path: '', component: comp },
]
但是,假设我们想要从API检索角色,从而异步。有什么方法可以实现这个目标?
答案 0 :(得分:8)
Angular 2支持模块级别的延迟加载。功能模块是异步加载的,而不是组件。 您可以制作该组件功能模块。 https://angular.io/docs/ts/latest/guide/ngmodule.html
答案 1 :(得分:8)
你可以创建一个generic.module.ts,它将在声明数组中包含两个组件:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { UserDashboardComponent } from './user-dashboard.component'
import { AdminDashboardComponent } from './admin-dashboard.component
@NgModule({
imports: [ BrowserModule ],
declarations: [ UserDashboardComponent,AdminDashboardComponent ]
})
export class GenericModule { }
这样您将拥有一个包含要加载的模块的模块。
现在下一步将使用编译器异步加载它们: 在组件内部执行以下操作:
import {GenericModule} from './generic.module';
import { Component, Input,ViewContainerRef, Compiler, NgModule,ModuleWithComponentFactories,OnInit,ViewChild} from '@angular/core';
@Component({
selector: 'generic',
template: '<div #target></div>'
})
export class App implements AfterViewInit {
@ViewChild('target', {read: ViewContainerRef}) target: ViewContainerRef;
constructor(private compiler: Compiler) {}
ngAfterViewInit() {
this.createComponent('<u>Example template...</u>');
}
private createComponent(template: string,role:string) {
@Component({template: template});
const mod = this.compiler.compileModuleAndAllComponentsSync(GenericModule);
const factory = mod.componentFactories.find((comp) =>
//you can add your comparison condition here to load the component
//for eg. comp.selector===role where role='admin'
);
const component = this.target.createComponent(factory);
}
}
希望这有帮助。
答案 2 :(得分:4)
您可以定义更高级别的组件f.e.路线/仪表板中包含的DashboardComponent
然后,父组件应该根据异步条件在其模板中加载子组件。
这样你还需要使用* ngIf,但至少它不会使子组件模板混乱。
答案 3 :(得分:3)
由于您将为一个组件使用一个路由,因此一个解决方案是为该路由创建另一个组件,然后其模板可以引用这两个组件,但使用如下所示的ngIf:
<user-dashboard *ngIf="role==='user'"></user-dashboard>
<admin-dashboard *ngIf="role==='admin'"></admin-dashboard>
答案 4 :(得分:1)
我建议您使用路由器的导航方法以编程方式导航。因此,列出路由器文件中的所有可能路由。然后在组件中根据具体情况调用router.navigate()。
答案 5 :(得分:0)
非常好的解决方案可能是&#34;使用auth-guard&#34;。您可以尝试实现CanActivate / CanLoad接口,并将您的条件放在该类中。
根据条件,路线被激活。
示例:
import { Injectable } from '@angular/core';
import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot
} from '@angular/router';
import { Observable } from 'rxjs/Observable';
import { Router } from '@angular/router';
@Injectable()
export class AuthorizationGuard implements CanActivate {
constructor() {}
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot):
Observable<boolean> {
let url: string = state.url;
return this.canbeLoaded(url);
}
canbeLoaded(url: string): Observable<boolean> {
return Observable.of(true); //put your condition here
}
}