Developing a Tab component
- The consumer should use it like this:
 
<tabs>
  <tab tabTitle="Tab 1">
    Here's some content.
  </tab>
  <tab tabTitle="Tab 2">
    And here's more in another tab.
  </tab>
</tabs>
Create tabs component
import { Component, OnInit } from '@angular/core';
@Component({
  selector: 'my-tabs',
  templateUrl: './tabs.component.html',
  styleUrls: ['./tabs.component.scss']
})
export class TabsComponent implements OnInit {
  constructor() { }
  ngOnInit() {
  }
}
<ul>
  <li>Tab 1</li>
  <li>Tab 2</li>
</ul>
- Use the component with 
my-tabstag 
<my-tabs></my-tabs>
We need a place to show the tab content with ng-content
- Add ng-content in the template
 
<ul>
  <li>Tab 1</li>
  <li>Tab 2</li>
</ul>
<ng-content></ng-content>
- When using the component, put tab contents in 
<tabs>tag 
<my-tabs>
  <p>Tab content</p>
</my-tabs>
Create a tab element to replace <li>Tab 1</li> with the property tabTitle
import { Component, OnInit, Input } from '@angular/core';
@Component({
  selector: 'my-tab',
  templateUrl: './tab.component.html',
  styleUrls: ['./tab.component.scss']
})
export class TabComponent implements OnInit {
  @Input() tabTitle: string;
  constructor() { }
  ngOnInit() {
  }
}
<div>
  <ng-content></ng-content>
</div>
- Use the component like this:
 
<my-tabs>
  <my-tab tabTitle="tab1">
    Tab 1 content
  </my-tab>
  <my-tab tabTitle="tab2">
    Tab 2 content
  </my-tab>
</my-tabs>
Generate tabs dynamic
- Using 
*ngFordirective to generate li element 
<ul>
  <li *ngFor="let tab of tabs"></li>
</ul>
- Create 
tabsproperty in TabsComponent, get children component withContentChildren@ContentChildren(TabComponent) tabs: QueryList<TabComponent>;And
how to testcomponent with ViewChildren - Create test component in the spec file as the host
 
@Component({
  selector: 'test-my-tabs',
  template: ''
})
export class TestTabsComponent {
  constructor() { }
}
- Create html template in spec file
 
  const html = `
    <my-tabs>
      <my-tab tabTitle="tab1">
        Tab 1 content
      </my-tab>
      <my-tab tabTitle="tab2">
        Tab 2 content
      </my-tab>
    </my-tabs>
  `;
- Init Angular test component with the 
TestTabsComponent 
  beforeEach(async(() => {
    TestBed.configureTestingModule({
      declarations: [TestTabsComponent, TabsComponent, TabComponent]
    });
  }));
  beforeEach(() => {
    TestBed.overrideComponent(TestTabsComponent, { set: { template: html } });
    fixture = TestBed.createComponent(TestTabsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });
- Override the component template with 
TestBed.overrideComponentbefore creating the test component anddo not compile the component before override 
  beforeEach(() => {
    TestBed.overrideComponent(TabsComponent, { set: { template: html } });
    fixture = TestBed.createComponent(TabsComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });
- Then the children components will be created
 
  it('should display childrens components with the property tabs', () => {
    const tabs = fixture.debugElement.queryAll(By.css('li'));
    expect(tabs.length).toBe(2);
  });
- And we can get 
TabsComponent instancewith@ViewChild 
@Component({
  selector: 'test-my-tabs',
  template: ''
})
export class TestTabsComponent {
  @ViewChild(TabsComponent) tabs: TabsComponent;
  constructor() { }
}
  it('should active the first tab as default', () => {
    const tabsComponent = component.tabs;
    expect(tabsComponent.tabs.first.active).toBeTruthy();
    expect(tabsComponent.tabs.last.active).toBeFalsy();
  });
Switch the tab content when clicking the tab title
Test first
  it('should siwtch tab when clicking the title', () => {
    const tabTitles = fixture.debugElement.queryAll(By.css('li'));
    const secondTabTitle = tabTitles[tabTitles.length - 1].nativeElement;
    secondTabTitle.click();
    expect(component.tabs.tabs.first.active).toBeFalsy('the first tab is unactive');
    expect(component.tabs.tabs.last.active).toBeTruthy('the tab clicked is active');
  });
Then bind click event to selectTab method
  <li *ngFor="let tab of tabs" (click)="selectTab(tab)">
    
  </li>
  selectTab(tab: TabComponent) {
    this.tabs.forEach(x => x.active = false);
    tab.active = true;
  }