如何从Angular2和ng-bootstrap中的组件中的NgbTabSet访问'select'方法?

bik*_*guy 14 tabs ng-bootstrap angular

使用Angular 2.3.1和ng-bootstrap 1.0.0-alpha.18.我试图以编程方式从组件中选择基于ID的选项卡,而不是从模板中选择.目标是从URL中提取param并使用它来选择ngOnInit中的选项卡

模板

<section id="policy-terms">
<ngb-tabset>
  <ngb-tab title="Terms and Privacy" id="terms">
    <template ngbTabContent>
      <div class="container page-content">

      </div>
    </template>
  </ngb-tab>
  <ngb-tab title="Company Policy" id="policy">
    <template ngbTabContent>
      <div class="container page-content">

      </div>
    </template>
  </ngb-tab>

</ngb-tabset>
</section>
Run Code Online (Sandbox Code Playgroud)

和组件代码:

import { Component, OnInit } from '@angular/core';
import { NgbTabset } from '@ng-bootstrap/ng-bootstrap';

@Component({
  selector: 'app-policy-terms',
  templateUrl: './policy-terms.component.html',
  styleUrls: ['./policy-terms.component.scss'],
  providers: [
       NgbTabset
   ]
 })
 export class PolicyTermsComponent implements OnInit {

 constructor(
    public tabset: NgbTabset
  ) { }

  ngOnInit() {
    this.tabset.select('policy');
   }
}
Run Code Online (Sandbox Code Playgroud)

这只会产生一个错误:

控制台日志错误

我该如何访问此方法?

Chu*_*way 17

使用Ngb-TabSet进行路由

在AngularJs 1.x中使用ui-router设置名称路由是直截了当的.在带有Ng-Bootstrap的Angular 2中,它并不那么明显.从好的方面来说,您需要的是原生的Angular 2库.

设置路由配置

export const appRoutes: Routes =
    [
        { path: 'prospect/:prospectid/details', component: ProspectTabsView, data:{name:'details'} },
        { path: 'prospect/:prospectid/appointments', component: ProspectTabsView, data:{name:'appointments'} },
        { path: 'prospect/:prospectid/followups', component: ProspectTabsView, data:{name:'followups'} },
        { path: 'prospect/:prospectid/contacts', component: ProspectTabsView, data:{name:'contacts'} },
        { path: '', component: DashboardView },
        { path: '**', redirectTo: '', pathMatch: 'full'}
    ];
Run Code Online (Sandbox Code Playgroud)

配置很简单,只有一个例外:[data]属性.你会注意到它有一个叫做的密钥name.这是路线的名称.将其视为数据包作为数据包.您可以添加多个路径名称.

设置TabSet标记

<ngb-tabset #tabs>
    <ngb-tab id="details">
        <ng-template ngbTabTitle>
            <a [routerLink]="['/prospect', prospectId, 'details']">Details</a>
        </ng-template>
        <ng-template ngbTabContent>
        </ng-template>
    </ngb-tab>
    <ngb-tab id="contacts">
        <ng-template ngbTabTitle>
            <a [routerLink]="['/prospect',prospectId,'contacts']">Contacts</a>
        </ng-template>
        <ng-template ngbTabContent>
        </ng-template>
    </ngb-tab>
    <ngb-tab id="appointments">
        <ng-template ngbTabTitle>
            <a [routerLink]="['/prospect', prospectId, 'appointments']">Appointments</a>
        </ng-template>
        <ng-template ngbTabContent>
        </ng-template>
    </ngb-tab>
    <ngb-tab id="followups">
        <ng-template ngbTabTitle>
            <a [routerLink]="['/prospect', prospectId, 'followups']">Follow Ups</a>
        </ng-template>
        <ng-template ngbTabContent>
        </ng-template>
    </ngb-tab>
</ngb-tabset>
Run Code Online (Sandbox Code Playgroud)

上面的标签标记没什么神奇之处,有几件事要注意:首先是在ngb-tabset元素中,我们已经声明了变量#tab.我们稍后会#tab在组件中使用.其次,每个nbg-tab都有一个id匹配我们在路由配置中定义的名称的集合(即data:{name:'followups'}).

设置组件

import {
     AfterViewChecked, Component, OnInit, 
    ViewChild
} from '@angular/core';
import '../../assets/css/styles.css';
import {ActivatedRoute} from "@angular/router";
import {NgbTabset} from "@ng-bootstrap/ng-bootstrap";

@Component({
    templateUrl: './tabs.view.html'
})
export class ProspectTabsView implements OnInit, AfterViewChecked{
    prospectId: number;
    selectedTab:string; 

    @ViewChild('tabs')
    private tabs:NgbTabset;

    constructor(private route: ActivatedRoute) { 
        this.route.data.subscribe(d=>{
            this.selectedTab = d.name;
        });
    }

    ngOnInit(): void {
        this.route.params.subscribe(
            params => {
                this.prospectId = +params['prospectid'];
            }
        );
    }

    ngAfterViewChecked(): void {
        if(this.tabs) {
            this.tabs.select(this.selectedTab);
        }
    } 
 }
Run Code Online (Sandbox Code Playgroud)

本练习中最难的部分是使执行顺序正确.如果不正确,则在操作之前不会初始化集合或属性.我们将从课堂顶端开始,向下工作.

首先,我们有变量.prospectId是数据的主键,selectedTab是当前所选选项卡的名称,最后,我们有tabs变量.tabs是对#tab我们添加到ngb-tabset元素的attribute()的引用.

接下来是constructor.它在文档中并不明显,但它data是一个Observable<data>.为了捕获价值,我们订购了data该路线的房产.

以下constuctorngOnInit.这对选项卡并不重要,但它确实捕获了我们在选项卡路由中使用的prospectId.如果您的路线中没有任何动态数据,那么您不需要这样.

最后,我们有ngAfterViewChecked.对于路由tabs,这是最重要的.这里我们使用tabs从标记中捕获的变量,然后我们将选定的选项卡名称传递tabs给更改选定选项卡的位置.

更新

为了使这个工作正常,我不得不添加钩子到tabChange事件上ngb-tabset.

HTML:

<ngb-tabset [activeId]="selectedTab" #tabs (tabChange)="onTabChange($event)">
Run Code Online (Sandbox Code Playgroud)

打字稿:

此外,我不得不在onTabChange函数中硬编码路由.

onTabChange($event: NgbTabChangeEvent) {
    let routes = {
        details: `/prospect/${this.prospectId}/details`,
        appointments: `/prospect/${this.prospectId}/appointments`,
        followups: `/prospect/${this.prospectId}/followups`,
        notes: `/prospect/${this.prospectId}/notes`,
        dials: `/prospect/${this.prospectId}/dials`,
    };

    this.router.navigateByUrl(routes[$event.nextId]);
}
Run Code Online (Sandbox Code Playgroud)


mis*_*130 1

在元素上放置引用

<ngb-tabset #tabs>
Run Code Online (Sandbox Code Playgroud)

使用 ViewChild 来控制选项卡

export class PolicyTermsComponent implements OnInit {
  private tabs:NgbTabset;

  @ViewChild('tabs')  public set _tabs(tabs: NgbTabset)
  {
     if(!tabs) return;
     this.tabs = _tabs;
     this.tabs.select('policy');
  }
}
Run Code Online (Sandbox Code Playgroud)

我将选择的执行移到了一个集合中,以确保页面正确创建了选项卡组件并且可以引用和使用它。