2016-12-15 117 views
2

這是我app.component.ts:如何在TabView(PrimeNG)中加載Angular 2組件?

import { Component } from '@angular/core'; 

@Component({ 
    templateUrl: 'app/app.component.html', 
    selector: 'my-app' 
}) 
export class AppComponent { 

} 

這是我app.component.html:

<p-tabView> 
    <p-tabPanel header="Home" leftIcon="fa-bar-chart-o"> 
     <home-app></home-app> 
    </p-tabPanel> 
    <p-tabPanel header="Hierarquia" leftIcon="fa-sitemap"> 
     <tree-app></tree-app> 
    </p-tabPanel> 
    <p-tabPanel header="Configurações" leftIcon="fa-cog"> 
     <config-app></config-app> 
    </p-tabPanel> 
</p-tabView> 

我的三個組成部分(家庭,樹和配置)在被加載同時加載tabView。但是,我希望組件在選擇其選項卡時加載。怎麼做?

P.S .:如果有幫助,TabView有一個onChange事件。

+0

你是怎麼知道的? –

+0

嗨,@羅曼C。抱歉。我怎麼知道什麼? –

+0

*在加載tabView的同時,我的三個組件(home,tree和config)被加載* - 你是怎麼知道的? –

回答

4

見大量的研究後,我可以解決使用路由器問題。現在應用程序非常快。

app.component.ts:

import { Component } from '@angular/core'; 
import { Router } from '@angular/router'; 

@Component({ 
    templateUrl: 'app/app.component.html', 
    selector: 'my-app' 
}) 
export class AppComponent { 

    constructor(
     private router: Router) { 
    } 

    handleChange(e) { 
     let index = e.index; 
     let link; 
     switch (index) { 
      case 0: 
       link = ['/home']; 
       break; 
      case 1: 
       link = ['/hierarquia']; 
       break; 
      case 2: 
       link = ['/config']; 
       break; 
     } 
     this.router.navigate(link); 
    } 
} 

app.component.html:

<div> 
    <p-tabView (onChange)="handleChange($event)"> 
     <p-tabPanel header="Home" leftIcon="fa-bar-chart-o"></p-tabPanel> 
     <p-tabPanel header="Hierarquia" leftIcon="fa-sitemap"></p-tabPanel> 
     <p-tabPanel header="Configurações" leftIcon="fa-cog"></p-tabPanel> 
    </p-tabView> 
</div> 

<router-outlet></router-outlet> 

app.route.ts:

import { NgModule } from '@angular/core'; 
import { Routes, RouterModule } from '@angular/router'; 

import { AppHome } from './app.home'; 
import { AppTree } from './app.tree'; 
import { AppConfig } from './app.config'; 

const routes: Routes = [ 
    { 
     path: 'home', 
     component: AppHome 
    }, 
    { 
     path: 'hierarquia', 
     component: AppTree 
    }, 
    { 
     path: 'config', 
     component: AppConfig 
    }, 
    { 
     path: '', 
     redirectTo: '/home', 
     pathMatch: 'full' 
    }, 
]; 

@NgModule({ 
    imports: [RouterModule.forRoot(routes)], 
    exports: [RouterModule] 
}) 
export class AppRoutingModule { } 

export const routedComponents = [AppHome, AppTree, AppConfig]; 

app.module.ts:

import { NgModule } from '@angular/core'; 
import { FormsModule, ReactiveFormsModule } from '@angular/forms'; 
import { HttpModule } from '@angular/http'; 
import { BrowserModule } from '@angular/platform-browser'; 
import 'rxjs/add/operator/toPromise'; 

import { AppConfig } from './app.config'; 
import { AppHeader } from './app.header'; 
import { AppHome } from './app.home'; 
import { AppTree } from './app.tree'; 
import { AppComponent } from './app.component'; 

import { AppRoutingModule, routedComponents } from './app.route'; 

import { InputTextModule, DataTableModule, ButtonModule, DialogModule, TabViewModule, ChartModule, TreeModule, GrowlModule, InputSwitchModule, BlockUIModule, InputMaskModule, DropdownModule } from 'primeng/primeng'; 

@NgModule({ 
    imports: [BrowserModule, FormsModule, ReactiveFormsModule, HttpModule, AppRoutingModule, InputTextModule, DataTableModule, ButtonModule, DialogModule, TabViewModule, ChartModule, TreeModule, GrowlModule, InputSwitchModule, BlockUIModule, InputMaskModule, DropdownModule], 
    declarations: [AppHeader, AppComponent, AppHome, AppTree, AppConfig, routedComponents], 
    bootstrap: [AppHeader, AppComponent] 
}) 
export class AppModule { } 

謝天謝地! =]

+0

看起來很完美,與第一個答案相比,它看上去很乾淨,並且與角度2標準一致。 –

7

您可以使用SystemJsNgModuleLoader這是在angular2路由

Live Plunker

enter image description here

首先,你可以寫組件將加載模塊一起使用:

@Component({ 
    selector: 'dynamic-container', 
    template: ` 
    <template #container></template> 
    <div *ngIf="!loaded" class="loader"></div> 
    `, 
    styles: [` 
    .loader { 
     position: relative; 
     min-height: 100px; 
    } 

    .loader:after { 
     content: 'Loading module. Please waiting...'; 
     position: absolute; 
     top: 50%; 
     left: 50%; 
     transform: translate(-50%, -50%); 
    } 
    `] 
}) 
export class DynamicContainerComponent implements OnDestroy { 
    @ViewChild('container', { read: ViewContainerRef }) vcRef: ViewContainerRef; 
    loaded: boolean; 

    constructor(private moduleLoader: SystemJsNgModuleLoader) { } 

    compRef: ComponentRef<any>; 

    @Input() modulePath: string; 
    @Input() moduleName: string; 

    _inited: boolean 
    set inited(val: boolean) { 
    if(val) { 
     this.loadComponent(); 
    } 
    this._inited = val; 
    }; 

    get inited() { 
    return this._inited; 
    } 

    loadComponent() { 
    this.moduleLoader.load(`${this.modulePath}#${this.moduleName}`) 
     .then((moduleFactory: NgModuleFactory<any>) => { 
     const vcRef = this.vcRef; 
     const ngModuleRef = moduleFactory.create(vcRef.parentInjector); 
     const comp = ngModuleRef.injector.get(LazyLoadConfig).component; 
     const compFactory = ngModuleRef.componentFactoryResolver.resolveComponentFactory(comp); 
     this.compRef = vcRef.createComponent(compFactory, 0, ngModuleRef.injector); 

     this.loaded = true; 
     }); 
    } 

    ngOnDestroy() { 
    this.compRef.destroy(); 
    } 
} 

然後用它在你的組件中:

@Component({ 
    selector: 'my-app', 
    template: ` 
    <h2 class="plunker-title">How to lazy load Angular 2 components in a TabView (PrimeNG)?</h2> 
    <p-tabView (onChange)="handleChange($event)"> 
    <p-tabPanel header="Home" leftIcon="fa-bar-chart-o"> 
     <home-app></home-app> 
    </p-tabPanel> 
    <p-tabPanel header="Hierarquia" leftIcon="fa-sitemap"> 
     <dynamic-container modulePath="./src/modules/tree/tree.module" moduleName="TreeModule"></dynamic-container> 
    </p-tabPanel> 
    <p-tabPanel header="Configurações" leftIcon="fa-cog"> 
     <dynamic-container modulePath="./src/modules/config/config.module" moduleName="ConfigModule"></dynamic-container> 
    </p-tabPanel> 
</p-tabView> 
    ` 
}) 
export class AppComponent { 
    @ViewChildren(DynamicContainerComponent) dynamicContainers: QueryList<DynamicContainerComponent>; 

    handleChange(e) { 
    let dynamicContainer = this.dynamicContainers.toArray()[e.index - 1]; 
    if (!dynamicContainer || dynamicContainer.inited) return; 

    // prevent fast clicking and double loading 
    dynamicContainer.inited = true; 
    } 
} 

+0

它幫了我很多! –

0

Primeng tabview有一個默認爲「false」的「懶」屬性。 您可以將其設置如下

<p-tabView [lazy]="true"> 
0

我試過懶惰的屬性,它不起作用。使用路由器和ModuleLoader很棒,但有點複雜。如果你想讓你的應用程序不太複雜,最簡單的解決方案是使用NgIf來渲染製表符。

<p-tabView (onChange)="handleChange($event)"> 
    <p-tabPanel header="Home" leftIcon="fa-bar-chart-o"> 
     <home-app *ngIf="activeTab === 0"></home-app> 
    </p-tabPanel> 
    <p-tabPanel header="Hierarquia" leftIcon="fa-sitemap"> 
     <tree-app *ngIf="activeTab === 1"></tree-app> 
    </p-tabPanel> 
    <p-tabPanel header="Configurações" leftIcon="fa-cog"> 
     <config-app *ngIf="activeTab === 2"></config-app> 
    </p-tabPanel> 
</p-tabView> 

並定義一個標誌來呈現選定的選項卡。

handleChange(e) { 
    this.activeTab = e.index; 
} 
相關問題