ng-bootstrap analysis component set assembly implemented tabset

The bootstrap: tabset

 This article describes the ng-bootstrap project, the realization of analysis tabset.

Use

<ngb-tabset>As the container element, to each of which a tab <ngb-tab>element definition, <ngb-tabset>contains a number of <ngb-tab>sub-elements.

In the <ngb-tab>elements, use <ng-template>templates to define the content, the content is divided into two types: the title and content.

The title using [ngbTabTitle]directive to declare, or <ngb-tab>use the element titleattribute declarations.

Content usage [ngbTabContent]instruction statement.

< NGB-tabset > 
  < NGB-tab title = "simple" > 
    < NG-template ngbTabContent > 
      < p > raw denim jean shorts Austin you probably have not heard of them. Do not make tofu stumptown some retro synth 
      master cleanse. Mustache cliché time, Williamsburg Carles Swiss vegan. Butcher criticized back keffiyeh 
      dreamcatcher synth. Cosby sweater football banh lord; for that cupidatat Terry Richardson from the squid. Aliquip he may please the salvia cillum 
      iphone. Seitan aliquip any man cardigan, american apparel, butcher pleasure, if not who. </ P > 
    </ NG-templates >
  NGB-tab > 
  < NGB-tab > 
    < NG-template ngbTabTitle > < B > Fancy </ b > Title </ NG-templates > 
    < NG-template ngbTabContent > Food Truck fixie Locavore, accusing McSweeney's Marfa is no single-origin coffee squid .
      < P > Exercitation +1 labor wants blog sartorial PBR leggings next level Wes Anderson artisan Four Loko farm-to-table 
      craft beer twee. Qui photo booth letterpress, commodo enim craft beer mlkshk aliquip jean shorts ullamco ad vinyl
      cillum PBR. A man nostrud organic, at once take a great effort was selected for the aesthetic is mollified. Keytar Swiss VHS sage 
      yr, the wise man, however, the labor of a great wish to stumptown. Vegan fanny pack cillum hate Wes Anderson 8-bit, sustainable jean 
      shorts heard that the DIY ethical fault Terry Richardson biodiesel. Art party scenester stumptown, tumblr batcher, however, 
      there are some who accuse the wise man tattooed Echo Park. </ P > 
    </ NG-template > 
  </ NGB-tab > 
  < NGB-tab title = "disabled" [disabled] = "true" > 
    < NG-template ngbTabContent > 
      <> But the convenience, the lion but it takes longer than an airline sapien members need elit diam. Nulla. Donec egestas ligula vitae odio Donec interdum aliquet. Graduated high school homework, grief need developers, top and hardware. Homework quiver players at the throat. Each arc of mourning for volleyball, basketball and graduated and television. But the pot diameter, connected to him or, weekend or weekend. Present ecological macro alcohol. Vivamus faucibus nisl, nor do I eros ipsum interdum euismod facilisis. Soccer and drink, the developers hate football. Various clinical Penatibus Super Bowl mountains instantly. , The clinic, nor hatred of ac lorem aliquet ultricies mauris aliquet. Eu boat or macro or ceramic pillow. </ P > 
    </ NG-template > 
  </roaring-tab > 
</ roaring tabset >

 

You can see, the outer element is <ngb-tabset>.

Each tab using the element <ngb-tab>definitions, tab content using the <ng-template>template definition, content tab is divided into two parts: the title and content.

Here is the title of the template

<ng-template ngbTabTitle><b>Fancy</b> title</ng-template>

 

The title can also be in ngb-tabuse on the [title]attribute definition. E.g:

<ngb-tab title="Disabled" [disabled]="true">

 

Content portion is defined, as used herein, instructions [ngbTabContent]for easy identification.

< NG-template ngbTabContent > 
    < p > But the convenience, the lion but it takes longer than an airline sapien members need elit diam. 
    </ P > 
</ NG-templates >

 

 

TabSet component definition

As can be seen from the previous use, defining all tab are ngb-tabsetcontent elements that define when in use, rather than ngb-tabsedefine their own templates.

So find they need to use ContentChildren to find.

@ContentChildren(NgbTab) tabs: QueryList<NgbTab>;

 

Do not use ContentChild reason is that it does not provide descendantssupport.

In the bootstrap, each tab is actually rendered into two parts, a list of titles, and content currently displayed.

Use a list of titles ulto handle. Which use a loop to all of the title is displayed.

And titleTplis defined by the template, it is used [ngTemplateOutlet]to render it.

<ul [class]="'nav nav-' + type + (orientation == 'horizontal'?  ' ' + justifyClass : ' flex-column')" role="tablist">
    <li class="nav-item" *ngFor="let tab of tabs">
        <a [id]="tab.id" class="nav-link" 
           [class.active]="tab.id === activeId" 
           [class.disabled]="tab.disabled"
           href (click)="select(tab.id); $event.preventDefault()" 
           role="tab" 
           [attr.tabindex]="(tab.disabled ? '-1': undefined)"
           [attr.aria-controls]="(!destroyOnHide || tab.id === activeId ? tab.id + '-panel' : null)"
          [attr.aria-selected]="tab.id === activeId" [attr.aria-disabled]="tab.disabled">
          {{tab.title}}<ng-template [ngTemplateOutlet]="tab.titleTpl?.templateRef"></ng-template>
        </a>
    </li>
</ul>

 

 

title section uses two sources side by side

{{tab.title}}<ng-template [ngTemplateOutlet]="tab.titleTpl?.templateRef"></ng-template>

 

Content part, due to the specific content using the template definition is out, so here is the use of [ngTemplateOutlet]rendered.

<div class="tab-content">
    <ng-template ngFor let-tab [ngForOf]="tabs">
        <div
          class="tab-pane {{tab.id === activeId ? 'active' : null}}"
          *ngIf="!destroyOnHide || tab.id === activeId"
          role="tabpanel"
          [attr.aria-labelledby]="tab.id" id="{{tab.id}}-panel">
          <ng-template [ngTemplateOutlet]="tab.contentTpl?.templateRef"></ng-template>
        </ >the-template</>Div
    
</div>

 

Projection content needs to Contentdeal with the type of event.

ngAfterContentChecked() {
    // auto-correct activeId that might have been set incorrectly as input
    let activeTab = this._getTabById(this.activeId);
    this.activeId = 
        activeTab ? activeTab.id : (this.tabs.length ? this.tabs.first.id : null);
}

 

 

Instruction defines two

Definition instruction is very simple, is to get a reference template for subsequent use.

You can see the attribute name is templateRef

@Directive({selector: 'ng-template[ngbTabTitle]'})
export class NgbTabTitle {
  constructor(public templateRef: TemplateRef<any>) {}
}

 

This is [ngbTabContent]the definition, the same as above, still defines the attributes templateRef.

@Directive({selector: 'ng-template[ngbTabContent]'})
export class NgbTabContent {
  constructor(public templateRef: TemplateRef<any>) {}
}

 

 

Tab definitions

Element type of instruction, so even the template are gone.

@Directive ({selector: 'roaring-tab'})

 

Content is projected to come in.

Since the tabuse of the template, and uses it to identify the command, they are defined in the assembly of the template, it is used here ContentChildrento identify.

@ContentChildren(NgbTabTitle, {descendants: false}) titleTpls: QueryList<NgbTabTitle>;
@ContentChildren(NgbTabContent, {descendants: false}) contentTpls: QueryList<NgbTabContent>

 

Since you can use titleTplsand contentTplsto use a template.

Because it is content, you need contentevent processing, in fact, in each tab, we have only one title and content of a statement.

ngAfterContentChecked() {
    // We are using @ContentChildren instead of @ContentChild as in the Angular version being used
    // only @ContentChildren allows us to specify the {descendants: false} option.
    // Without {descendants: false} we are hitting bugs described in:
    // https://github.com/ng-bootstrap/ng-bootstrap/issues/2240
    this.titleTpl = this.titleTpls.first;
    this.contentTpl = this.contentTpls.first;
}

See also

Guess you like

Origin www.cnblogs.com/haogj/p/11210861.html