2017-01-09 88 views
2

我用一個非常簡單的方法,這樣的選項卡式UI:爲組件Angular2事件出現/消失

<div *ngIf="active" class="pane"> 
    <ng-content></ng-content> 
</div> 

主動當標籤被選中時設置爲true的組件。

裏有標籤的多個組件,從web服務的所有民意調查數據,相關代碼:

export class DebugComponent implements OnInit { 
    public timerSubscription: Subscription; 

    ngOnInit() { 
    this.startTimer(0); 
    } 

    private startTimer(delay: number){ 
    let timer = Observable.timer(delay, 1000); 
    this.timerSubscription = timer.subscribe(x => this.execute()); 
    } 

    private stopTimer(){ 
    this.timerSubscription.unsubscribe(); 
    } 

    execute() { 
    this.stopTimer(); 
    // do stuff 
    this.startTimer(5); 
    } 
} 

雖然它運作良好,開始使用ngOnInit計時,我發現沒有辦法阻止它的時候該組件將從可見DOM中移除。

當ngIf條件中的組件從可見DOM中被移除以停止定時器時,通知最佳方法是什麼?

感謝,

UPDATE:整個故事

感謝岡特,我想出解決問題的辦法。因爲我認爲這是一個常見的要求,所以我會嘗試把所有的部分放在一起(不是完整的複製和粘貼現成的代碼,而是所有需要的部分):

一個簡單的選項卡組件,基於此http://blog.thoughtram.io/angular/2015/04/09/developing-a-tabs-component-in-angular-2.html

主要翼片組件包含選項卡:

凸片-component.ts

import {Component, ContentChildren, QueryList, AfterContentInit} from '@angular/core'; 
import {TabComponent} from './tab.component'; 

@Component({ 
    selector: 'tabs', 
    template: ` 
    <ul class="nav nav-tabs"> 
     <li *ngFor="let tab of tabs" (mouseup)="selectTab(tab)" [class.active]="tab.active"> 
     <a href="#">{{tab.title}}</a> 
     </li> 
    </ul> 
    <ng-content></ng-content> 
    ` 
}) 
export class TabsComponent implements AfterContentInit { 

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

    // contentChildren are set 
    ngAfterContentInit() { 
    // get all active tabs 
    let activeTabs = this.tabs.filter((tab) => tab.active); 

    // if there is no active tab set, activate the first 
    if (activeTabs.length === 0) { 
     this.selectTab(this.tabs.first); 
    } 
    } 

    selectTab(selectedTab: TabComponent) { 
    // deactivate active tab 
    this.tabs.filter((tab) => tab.active).forEach(tab => tab.disable()); 

    // activate the tab the user has clicked on. 
    selectedTab.activate(); 
    } 

} 

的選項卡組件把凸片部件內部:

製表component.ts

import {Component, Input, ContentChildren, QueryList} from '@angular/core'; 
import {TabChild} from "./tab.child"; 

@Component({ 
    selector: 'tab', 
    styles: [` 
    .pane{ 
     padding: 1em; 
    } 
    `], 
    template: ` 
    <div *ngIf="active" class="pane"> 
     <ng-content></ng-content> 
    </div> 
    ` 
}) 
export class TabComponent { 
    @Input('tabTitle') title: string; 
    @Input() active = false; 

    @ContentChildren(TabChild) content:QueryList<TabChild>; 

    public activate(){ 
    this.active = true; 
    this.content.toArray().forEach(dc => dc.tabActivated()); 
    } 

    public disable(){ 
    this.active = false; 
    this.content.toArray().forEach(dc => dc.tabDisabled()); 
    } 
} 

顯示內的卡口需要從該基類繼承的組件:

製表child.ts

import {Directive} from "@angular/core"; 

@Directive({selector: "TabChild"}) 
export class TabChild { 
    public tabActivated() : void{} 
    public tabDisabled() : void{} 
} 

示例組件如下所示:

樣本組件。TS

import {Component, ApplicationRef, forwardRef} from '@angular/core'; 
import {TabChild} from "./tab.child"; 

@Component({ 
    selector: 'sample', 
    templateUrl: "app/sample.component.html", 
    providers: [{provide: TabChild, useExisting: forwardRef(() => SampleComponent) }] 
}) 
export class SampleComponent implements TabChild { 

    tabActivated(): void { 
    console.log("Sample tabActivated"); 
    } 

    tabDisabled(): void { 
    console.log("Sample tabDisabled"); 
    } 
} 

全部放在一起:

@Component({ 
    selector: "my-app", 
    template: `<tabs> 
    <tab tabTitle="Sample1"> 
     <sample></sample> 
    </tab> 
    <tab tabTitle="Sample2"> 
     <sample></sample> 
    </tab> 
    </tabs>` 
}) 

回答

1

可以使用ngOnDestroy生命週期回調

export class DebugComponent implements OnInit, OnDestroy { 

    ngOnDestroy() { 
    this.stopTimer(); 
    } 

參見https://angular.io/docs/ts/latest/api/core/index/OnDestroy-class.html

+2

感謝岡特,但ngOnDestro當我切換選項卡時,y不會被調用(並且ngOnit每個組件只有一次,切換選項卡時不會)。我做錯了什麼,可能使用其他的東西然後ngIf會更好? –

+0

我錯過了'ngIf'只會刪除''而不是投影元素。你是對的,在這種情況下'* ngIf'不會破壞組件。 –

+0

當'active'變爲false時,您可以使用'@ContentChildren(DebugComponent)內容:QueryList ;'和'this.content.toArray()。forEach(dc => dc.setHidden())''。 –