2016-09-25 2 views
13

경로에 비동기 적으로 구성 요소를 연결하려면 조건 인 이 필요합니다.각도 2 : 경로에서 구성 요소를 조건부로 비동기 적으로로드하는 방법?

작동합니다 (그러나 비동기) 다음 예, 부하 하나 개의 구성 요소 또는 다른 사용자의 역할에 따라 : 따라서

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의 역할 를 검색하고 싶은 말은하자, 비동기식. 그 방법은 무엇입니까?

+1

(https://angular.io/docs/ts/latest/guide/router를 [여기].html) 및 "Lazy-Loading 라우트 구성"을 검색하십시오. – cvsguimaraes

+0

게으른 로딩이 도움이되지 않습니다. @ user32 대답에 대한 내 의견을 참조하십시오. –

+0

당신이 그것을 알아 냈습니까? – Dmitry

답변

7

각도 2는 모듈 수준에서 지연로드를 지원합니다. 지형지 물 모듈은 구성 요소가 아닌 비동기 적으로로드됩니다. 해당 구성 요소 기능 모듈을 만들 수 있습니다. https://angular.io/docs/ts/latest/guide/ngmodule.html

+2

죄송합니다. 제 자신을 올바르게 표현하지 않은 것 같습니다. 나는 "비동기 적"이라고 강조했지만 나의 문제는 "조건"에 관한 것입니다. 지연로드는 내 문제와 직접적으로 관련이 없습니다. 내 문제는 응용 프로그램이로드 될 때 비동기적일 수있는 조건에 따라 하나의 구성 요소 또는 다른 구성 요소 (또는 하나의 모듈 또는 다른 모듈)를로드하는 방법입니다 (즉, 조건은 API에서 제공되는 사용자 역할 임). 내 질문을 더 명확하게 업데이트했습니다. 그걸 해결할 방법이 있니? –

1

라우터의 navigate 메소드를 사용하여 프로그래밍 방식으로 탐색하는 방법에 대해 설명합니다. 따라서 라우터 파일에있는 모든 가능한 경로를 나열합니다. 구성 요소에서 특정 사례를 기반으로 router.navigate()를 호출합니다.

+1

이 경우 url은 같지 않습니다. – Manish

+0

정확히. 내가 원하는 것은 (적어도 처음에는)/url/dashboard라는 동일한 URL을 가지고 UserDashboard 또는 AdminDashboard를 표시하는 User 또는 Admin인지 여부를 결정하는 것입니다. 어쩌면 최선의 방법은 아니지만이 경우 다른 URL을 피하거나 심지어 모든 종류의 {{* ngIf}} 조건으로 구성 요소를 채우고 싶습니다. –

4

더 높은 수준의 구성 요소 f.e를 정의 할 수 있습니다. 경로/대시 보드에 포함 된 DashboardComponent

부모 구성 요소는 비동기 조건에 따라 템플릿에 하위를로드해야합니다.

이렇게하면 * ngIf를 사용해야하지만 적어도 하위 구성 요소 템플릿이 어지럽지 않아야합니다.

+0

이 말은 흥미롭고 합리적인 것 같습니다. 나는 여기에서하려고 노력할 것이다! 지금은 다른 답변을 환영하기 위해 스레드를 열어두고 있습니다. –

6

당신은 선언 배열의 두 구성 요소가됩니다 generic.module.ts을 만들 수 있습니다 Resolve에서 리디렉션을 수행하는 방법을 보여줍니다 공식 예입니다 https://angular.io/docs/ts/latest/api/router/index/Resolve-interface.html

:

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

희망이 도움이됩니다.

+1

이것은 많은 의미가 있습니다. 이 경우 저수준 프레임 워크 범위에서 특별히 많은 일을해야한다는 것은 놀라운 일입니다. 당분간 나는 이것을 받아 들일 수있는 대답이 될 수 없다. 왜냐하면 나는 이것을 위해 모호한 팀에게 문제를 열어주기를 원하기 때문이다. 그러나 그 대답이 그 현상금을 보상한다고 확신합니다. –

+0

@AlexJ이 소식을 듣고 나면 기꺼이 도움이 될 것입니다. –

+1

https://github.com/angular/angular/issues/12088 관심이있는 경우 문제가 발생했습니다 –

2

당신도 구성 요소에 대한 하나 개의 경로를 사용하는 것 때문에는, 하나 개의 솔루션은 다음의 템플릿은 다음과 같은 ngIf 두 구성 요소에 있지만 함께 참조 할 수있는 경로에 대한 또 다른 구성 요소를 만들 수 있습니다 :

<user-dashboard *ngIf="role==='user'"></user-dashboard> 
<admin-dashboard *ngIf="role==='admin'"></admin-dashboard> 
-1

아주 좋은 해결책 수 "auth-guard 사용"이되어야합니다. 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 
    } 
} 
관련 문제