2017-01-09 4 views
2

У меня есть вкладками интерфейс, используя очень простой подход, как это:Angular2 событие для компонента появляются/исчезают

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

Активный устанавливается истина на компоненте, когда становится выбрана вкладка.

Есть несколько компонентов в закладках, что все опросы данных из веб-сервиса, соответствующий код:

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.

Что было бы лучшим способом получить уведомление, когда компонент будет удален из видимой DOM условием ngIf, чтобы остановить таймер?

Спасибо,

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{} 
} 

Пример компонента выглядит следующим образом:

образец-компонент.ц

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 только один раз для каждого компонента, а не при переключении вкладок). Я что-то делаю неправильно, возможно, используя что-то еще, тогда лучше было бы? –

+0

Я пропустил, что 'ngIf' только удаляет' ', но не проецируемые элементы. Вы правы, в этом случае '* ngIf' не уничтожает компонент. –

+0

Вы можете использовать содержимое @ContentChildren (DebugComponent): QueryList ; 'и' this.content.toArray(). ForEach (dc => dc.setHidden()) ', когда' active' становится false. –

Смежные вопросы