import { Component , ContentChildren , QueryList , Input , ViewChildren , AfterViewInit , Output , EventEmitter , TemplateRef , ViewContainerRef , ComponentFactoryResolver , Type , ChangeDetectorRef } from '@angular/core' ; import { JigsawTabPane } from './tab-pane' ; import { JigsawTabContent , JigsawTabLabel } from './tab-item' ; import { AbstractJigsawComponent , IDynamicInstantiatable } from '../core' ; @ Component ( { selector : 'jigsaw-tab' , template : 'tab.html' } ) export class JigsawTab extends AbstractJigsawComponent implements AfterViewInit { constructor ( private _cfr , private _changeDetector , private _viewContainer ) { super ( ) ; } internal @ ContentChildren ( JigsawTabPane ) public _$tabPanes : QueryList < JigsawTabPane > ; @ ViewChildren ( JigsawTabLabel ) private _tabLabel : QueryList < JigsawTabLabel > ; @ ViewChildren ( JigsawTabContent ) private _tabContent : QueryList < JigsawTabContent > ; @ Output ( ) public selectChange = new EventEmitter < JigsawTabPane > ( ) ; public length : number ; internal public _$tabClick ( index ) { this . selectedIndex = index ; } internal public _$selectedIndex : number ; @ Input ( ) public get selectedIndex ( ) : number { return this . _$selectedIndex ; } public set selectedIndex ( value ) { if ( this . _$selectedIndex !== value && typeof value == 'number' ) { this . _$selectedIndex = value ; if ( this . initialized ) { this . _handleSelectChange ( value ) ; } this . _changeDetector . detectChanges ( ) ; } } @ Output ( ) public selectedIndexChange = new EventEmitter < number > ( ) ; private _handleSelectChange ( index ) { this . selectChange . emit ( this . _getTabPaneByIndex ( index ) ) ; this . selectedIndexChange . emit ( index ) ; this . _asyncSetStyle ( index ) ; } private _inkBarStyle : object = { } ; private _setInkBarStyle ( index ) { let labelPos = this . _getLabelOffsetByKey ( index ) ; this . _inkBarStyle = { display : 'block' , transform : 'translate3d(' + labelPos . offSet + 'px, 0px, 0px)' , width : labelPos . width + 'px' } ; } private _getLabelOffsetByKey ( key ) { let currentLabel = this . _tabLabel . find ( item => item . key === key ) ; if ( currentLabel ) { return { offSet : currentLabel . getOffsetLeft ( ) , width : currentLabel . getOffsetWidth ( ) } ; } else { console . warn ( '没有对应key的tab-Label' ) ; return { } ; } } private _getTabPaneByIndex ( key ) { return this . _$tabPanes . find ( ( item , index ) => index === key ) ; } private _autoSelect ( ) { this . selectedIndex = this . _$tabPanes . toArray ( ) . findIndex ( tabPane => ! tabPane . disabled && ! tabPane . hidden ) ; } private _asyncSetStyle ( index ) { setTimeout ( ( ) => { this . _setInkBarStyle ( index ) ; } , 0 ) ; } ngAfterViewInit ( ) { if ( this . selectedIndex != null ) { this . _handleSelectChange ( this . selectedIndex ) ; } else { this . _autoSelect ( ) ; } this . length = this . _$tabPanes . length ; } param key public hideTab ( index ) { let tabPane = this . _getTabPaneByIndex ( index ) ; if ( ! this . _isTabPane ( tabPane ) ) return ; tabPane . hidden = true ; this . _handleSelect ( ) ; } param index public showTab ( index ) { let tabPane = this . _getTabPaneByIndex ( index ) ; if ( ! this . _isTabPane ( tabPane ) ) return ; tabPane . hidden = false ; this . selectedIndex = index ; } private _isTabPane ( tabPane ) { if ( ! tabPane ) { console . info ( '没有找到对应的索引的tab-pane' ) ; return false ; } else { return true ; } } param tabPane public addTab ( title , content , initData ? ) { const factory = this . _cfr . resolveComponentFactory ( JigsawTabPane ) ; let tabPane = this . _viewContainer . createComponent ( factory ) . instance ; if ( typeof title == 'string' ) { tabPane . title = title ; } else { tabPane . label = title ; } tabPane . content = content ; tabPane . initData = initData ; let tabTemp = this . _$tabPanes . toArray ( ) ; tabTemp . push ( tabPane ) ; this . _$tabPanes . reset ( tabTemp ) ; this . length = this . _$tabPanes . length ; this . selectedIndex = this . _$tabPanes . length - 1 ; setTimeout ( ( ) => { let link = this . _tabLabel . find ( item => item . key === this . selectedIndex ) . elementRef . nativeElement . querySelector ( '[routerLink]' ) ; if ( link ) { link . click ( ) ; } } , 0 ) ; } param index public removeTab ( index ) { if ( this . _$tabPanes . length - index < 1 ) { console . info ( '没有对应tab-pane 供删除' ) ; return ; } let tabTemp = this . _$tabPanes . toArray ( ) ; tabTemp . splice ( index , 1 ) ; this . _$tabPanes . reset ( tabTemp ) ; this . length = this . _$tabPanes . length ; if ( this . selectedIndex == index ) { this . _handleSelect ( ) ; } else { this . selectedIndex = this . selectedIndex - 1 ; } } private private _handleSelect ( ) { let tabPane = this . _getTabPaneByIndex ( this . selectedIndex ) ; if ( ! tabPane || tabPane . hidden || tabPane . disabled ) { this . _autoSelect ( ) ; } else { this . _asyncSetStyle ( this . selectedIndex ) ; } } }