2017-11-22 27 views
3

탭에 구성 요소를로드하려고합니다. 특정 탭을 클릭하는 동안 특정 구성 요소를로드해야합니다. 그러나 해당 구성 요소를 탐색하는 동안 모든 구성 요소를로드하고 있습니다.탭을 클릭하는 동안 angular2의 특정 구성 요소를로드해야합니다.

.html 중에서

<p-tabView orientation="left" (onChange)="onTabChange($event)"> 
     <p-tabPanel *ngFor="let item of items" style="border: solid 1px; padding: 20px;margin: 20px;" [selected]="activeTabIndex==i"> 
       <strong> When you click here, 
       I should load the <span style="color:red"> {{item.name}} </span> 
       component below</strong> <br /> 

       <ng-container *ngComponentOutlet="childmap[item.name] "></ng-container> 

      <br /> 
     </p-tabPanel> 
</p-tabView> 

.TS

@Component({ 
    selector: 'my-app', 
    templateUrl:'dashboard.html' 
    ` 
}) 
export class App { 
activeTabIndex: number = 0; 

childmap = { 
     'slider': sliderComponent, 
     'user': usersComponent, 
     'alert danger': AlertDangerComponent 
     } 


items:Array<any> = [ 
    { 
     name: 'slider' 
    }, 
    { 
     name: 'user' 
    }, 
    { 
     name: 'alert danger' 
    } 

     ] 
onTabChange(event: any) { 
     this.activeTabIndex = event.index; 
    } 
    } 
+0

탭을 탭 안에 넣고 싶습니까? 귀하의' '는 이미''안에 있습니다. 또는'ngFor'를 사용하여 모든 탭 안에 단일 구성 요소를로드 하시겠습니까? –

+0

ngFor – Vignesh

답변

2

이런 종류의 솔루션에는 여러 가지가 있습니다. ngComponentOutlet을 사용하여 수행 한 작업을 수행하십시오. 누군가가 탭을 선택할 때

import {Component, Input} from '@angular/core' 
import {TabContentAlternativeComponent} from './tab-content-alternative.component' 
import {BasicContent} from './basic-content' 

@Component({ 
    selector: 'tab', 
    template: '' 
}) 
export class TabComponent { 
    @Input() title: string; 
    @Input() contentRef: BasicContent; 
    active = false; 
} 

이 자체 탭 이름을 알고 매우 간단한 구성 요소, 활성 상태 및로드되어야 몸체 요소 기준은 : 여기

는 탭 컨테이너 .2

다음
import {Component, Input} from '@angular/core' 
import {BasicContent} from './basic-content' 

@Component({ 
    selector: 'tab-content-alternative', 
    template: ` 
     <p>Hey, this is an alternative content</p> 
    `, 
}) 
export class TabContentAlternativeComponent extends BasicContent { 
} 

는 탭 -이다

export class BasicContent { 

} 

구성 요소 1

import {Component, Input, OnInit} from '@angular/core' 
import {BasicContent} from './basic-content' 

@Component({ 
    selector: 'tab-content', 
    template: ` 
     <p>Hey</p> 
    `, 
}) 
export class TabContentComponent extends BasicContent { 
} 

구성 요소 :

그런 다음 우리는 동적으로로드됩니다 여러 신체 구성 요소를 만들 기음 ontainer의 렌더링 탭 구성 요소 및 동적 신체 구성 요소에 대한 빈 자리 표시 자 :

import {TabContentComponent} from './tab/tab-content.component' 
import {TabContentAlternativeComponent} from './tab/tab-content-alternative.component' 

@Component({ 
    selector: 'my-app', 
    template: ` 
    <tab-container> 
     <tab title="Tab 1" [contentRef]="normalContent"></tab> 
     <tab title="Tab 2" [contentRef]="alternativeContent"></tab> 
    </tab-container> 
    `, 
}) 
export class App { 
    normalContent = TabContentComponent; 
    alternativeContent = TabContentAlternativeComponent; 
} 
:

import {AfterContentInit, Component, ContentChildren, QueryList} from '@angular/core' 
import {TabComponent} from './tab.component' 
import {BasicContent} from 'basic-content' 

import 'rxjs/Rx'; 
import {Observable, BehaviorSubject} from 'rxjs/Rx'; 

@Component({ 
    selector: 'tab-container', 
    template: ` 
    <div class="tab-header"> 
     <div class="tab" *ngFor="let tab of tabs" (click)="selectTab(tab)" [class.active]="tab.active">{{tab.title}}</div> 
    </div> 

    <div class="tab-content"> 
     <ng-container *ngComponentOutlet="content | async"></ng-container> 
    </div> 
    `, 
}) 
export class TabContainerComponent implements AfterContentInit { 
    @ContentChildren(TabComponent) tabs: QueryList<TabComponent>; 

    private contentSbj = new BehaviorSubject<BasicContent>(null); 
    content = this.contentSbj.asObservable(); 

    ngAfterContentInit() { 
    const activeTabs = this.tabs.filter((tab) => tab.active); 
    if (activeTabs.length === 0) { 
     this.selectTab(this.tabs.first); 
    } 
    } 

    selectTab(tab: TabComponent) { 
    this.tabs.toArray().forEach(tab => tab.active = false); 
    tab.active = true; 
    this.contentSbj.next(tab.contentRef); 
    } 
} 

TitleMapping

import {TabContentComponent} from './tab-content.component'; 
import {TabContentAlternativeComponent} from './tab-content-alternative.component'; 

interface TitleMapping { 
    title: string; 
    contentComponent: BasicContent; 
} 

export const allTabs: TitleMapping[] = [ 
    {title: "Tab 1", contentComponent: TabContentComponent}, 
    {title: "Tab 2", contentComponent: TabContentAlternativeComponent}, 
    {title: "Tab 3", contentComponent: TabContentComponent} 
] 

그리고이 그것이 어떤 부모 구성 요소에서 사용하는 방법입니다 여기

Plunkr

을하고있다

나는 이것을 나의 프로젝트에 사용했고, 당신의 요구 사항으로 잘 작동한다.

1

은 당신이하고있는 것은 기본적으로 자신의 라우터를 작성하려고합니다. PrimeNg TabView는 초기화시 메뉴와 모든 탭 내용을 먼저로드 한 다음 그 위에 탭의 인위적인 레이어를 둡니다. 그러나 메뉴 아래에는 TabMenu가 있습니다. 실제로는 원하는 것입니다. 주요 차이점은 메뉴가 라우터 목록을 매개 변수로 포함 할 수있는 MenuItems이 될 수 있다는 것입니다.

official documentation에 대해 선호하는 세부 사항을 설명하는 우수 기사 here가 있습니다. 우선이 사실을 이해하고, routerLink를 제공하면 PrimeNg가 이러한 링크를 구축하는 편리한 방법을 구현하는 방법을 알아야합니다. (MenuItem 모델에 대한 더 나은 문서를 보려면 MenuItems 링크를 참조하십시오. 코드에서 최상위 구성 요소인지 아닌지는 알 수 없지만,이 행을 따라 찾고있는 것으로 생각합니다.이 솔루션은 하위 경로를 사용합니다 빈 루트 대시 보드로 리디렉션으로하는 약간 더 복잡하지만 더 유용한 예. 이것은 당신이 AppComponent 그냥 <router-outlet></router-outlet> 템플릿으로 최고 수준의 구성 요소로 설정 있다고 가정합니다.이 대시 보드 구성 요소를로드합니다.

app.module.ts

const myDefinedRoutes: Routes = [ 
    {path: '', redirectTo: 'dashboard', pathMatch: 'full'}, 
    {path: 'dashboard', component: DashboardComponent, children: [ 
     {path: 'slider', component: SliderComponent}, 
     {path: 'user', component: UserComponent}, 
     {path: 'alert', component: AlertDangerComponent}, 
    ] 
    } 
] 

@NgModule({ 
    // Add this line to imports 
    RouterModule.forRoot(myDefinedRoutes) 
}) 
export class AppModule {} 

dashboard.component.ts

@Component({ 
    selector: 'my-app', 
    template:` 
    <p-tabMenu [model]="items"></p-tabMenu> 
    <router-outlet></router-outlet> 
    ` 
}) 
export class App implements OnInit { 
    ngOnInit() { 
    this.items = [ 
     {label: "Slider", routerLink: ['/dashboard', 'slider']}, 
     {label: "User", routerLink: ['/dashboard', 'user']}, 
     {label: "Danger", routerLink: ['/dashboard', 'alert']}, 
    ]; 
    this.activeItem = this.items[1] 
    } 
} 

다른 구성 요소는 제 1 출구는 여전히 대시 보드 구성 요소를 수용하기 때문에 다른 콘센트가 필요합니다 의미 자식으로 존재하고, 너무 때문에 대시 보드 구성 요소에서 라우터 콘센트를 포함해야합니다 대시 보드 구성 요소 내부 , 당신은 다른 세 가지 구성 요소 중 하나를 보여주고 있습니다.

+0

을 사용하여 모든 탭 내부에 단일 구성 요소를로드하려고 할 때마다 탭을 전환 할 때마다 다시로드됩니까? – Krishnan

+0

귀하의 질문을 올바르게 이해한다면 예. 라우팅을 사용할 때 ActivatedRoute가 변경 될 때마다 라우터 출력의 내용이 ngOnInit을 호출하고 구성 요소 수명주기를 진행하는 라우터 출력 내부의 구성 요소를 다시 작성합니다. 답장을 보내 주셔서 감사합니다. – Murphy4

+0

각도 탭 안에 동적 구성 요소를로드해야하는 비슷한 요구 사항에 직면하고 있습니다. 하지만 내가 게시물 https://stackoverflow.com/questions/47879472/how-to-load-the-angular-components-dynamically-in-a-angular-tab에서 설명한 몇 가지 문제에 직면하고있다 ... 만약 가능하면이 문제를 해결할 수 있도록 도와 주시겠습니까? – Krishnan