单击选项卡时,我需要在 angular2 中加载特定组件
While clicking on tab i need to load particular component in angular2
我正在尝试在选项卡中加载组件。单击特定选项卡时我需要加载特定 component.But 它在导航到该组件时加载所有组件。
.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;
}
}
你所做的基本上是在尝试编写你自己的路由器。 PrimeNg TabView 被构建为首先在初始化时加载菜单和所有选项卡内容,然后在其上放置一个人工选项卡层。但是,在菜单下,有 TabMenu 这实际上是你想要的。关键区别在于菜单允许您的列表 MenuItems 可以包含 routerLink 作为参数。
有一篇很棒的文章here that explains the details which I prefer to the official documentation。您应该首先了解这一点,然后看看 PrimeNg 如何实现一种方便的方法来为您构建这些 links(如果您提供 routerLink)。 (有关 MenuItem 模型的更好文档,请参阅 MenuItems link。从您的代码中我无法判断您是否在顶级组件中,但我认为您正在寻找的是沿着这些方向。这解决方案使用稍微复杂一点的子路由,但这是一个更有用的示例。这假设您将 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]
}
}
确保你在仪表板组件中也包含路由器插座,因为其他组件作为子组件存在,这意味着你将需要另一个插座,因为第一个插座仍然容纳仪表板组件,并且在仪表板组件内部,你正在显示其他三个组件之一。
这种事情有很多解决办法。请使用 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;
}
这是一个非常简单的组件,它知道自己的选项卡名称、活动状态和当有人选择选项卡时应该加载的正文组件引用。
然后我们创建几个动态加载的主体组件:
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 {
}
组件 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 {
}
这是带有选项卡渲染和动态主体组件的空占位符的选项卡容器组件:
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}
]
这就是它在某些父组件中的使用方式:
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;
}
这里正在工作Plunkr
我已经在我的项目中使用了它,并且按照您的要求工作得很好。
我正在尝试在选项卡中加载组件。单击特定选项卡时我需要加载特定 component.But 它在导航到该组件时加载所有组件。
.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;
}
}
你所做的基本上是在尝试编写你自己的路由器。 PrimeNg TabView 被构建为首先在初始化时加载菜单和所有选项卡内容,然后在其上放置一个人工选项卡层。但是,在菜单下,有 TabMenu 这实际上是你想要的。关键区别在于菜单允许您的列表 MenuItems 可以包含 routerLink 作为参数。
有一篇很棒的文章here that explains the details which I prefer to the official documentation。您应该首先了解这一点,然后看看 PrimeNg 如何实现一种方便的方法来为您构建这些 links(如果您提供 routerLink)。 (有关 MenuItem 模型的更好文档,请参阅 MenuItems link。从您的代码中我无法判断您是否在顶级组件中,但我认为您正在寻找的是沿着这些方向。这解决方案使用稍微复杂一点的子路由,但这是一个更有用的示例。这假设您将 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]
}
}
确保你在仪表板组件中也包含路由器插座,因为其他组件作为子组件存在,这意味着你将需要另一个插座,因为第一个插座仍然容纳仪表板组件,并且在仪表板组件内部,你正在显示其他三个组件之一。
这种事情有很多解决办法。请使用 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;
}
这是一个非常简单的组件,它知道自己的选项卡名称、活动状态和当有人选择选项卡时应该加载的正文组件引用。
然后我们创建几个动态加载的主体组件:
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 {
}
组件 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 {
}
这是带有选项卡渲染和动态主体组件的空占位符的选项卡容器组件:
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}
]
这就是它在某些父组件中的使用方式:
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;
}
这里正在工作Plunkr
我已经在我的项目中使用了它,并且按照您的要求工作得很好。