单击选项卡时,我需要在 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

我已经在我的项目中使用了它,并且按照您的要求工作得很好。