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

有很多解决方案。请使用ngComponentOutlet

我做了什么。

这是tab-container:

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

我已经将其用于我的项目,并且可以正常工作作为您的要求。

您正在做的事情基本上是在尝试编写自己的路由器。Primeng TabView的构建是为了加载菜单,首先在初始化时首先将所有选项卡中的内容放在其顶部。但是,在菜单下,有TabMenu实际上是您想要的。关键区别在于菜单允许您的列表为benuitems,其中可能包括路由链接作为参数。

这里有一篇很棒的文章,解释了我更喜欢正式文档的细节。您应该首先了解这一点,然后看看Primeng如何实现一种方便的方式,如果您提供RouterLink,则如何为您构建这些链接。(有关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]
  }
}

请确保在仪表板组件中也将路由器输出包装在仪表板组件中,因为其他组件是孩子的,这意味着您将需要另一个插座,因为第一个插座仍在包含仪表板组件,并且在仪表板组件中,您正在显示其他三个组件之一。

相关内容

  • 没有找到相关文章

最新更新