1

I use angular-seed template for my angular2 app. And I wrote a simple stopwatch. If i start the timer and change the route, the component will be destroyed and the timer stops. How can I prevent this? The timer should work in the background.

import {Component, ElementRef} from "@angular/core";
import {WindowService} from "../services/window.service";

@Component({
    selector: 'timer',
    template: `<div>
                <span>0</span><br>
                <button (click)="start()">start</button>
                <button (click)="stop()">stop</button>
                </div>`
})

export class TimerDirective {

    private running:boolean;
    private time:number;
    private results:Array<any>;
    private laps:Array<string>;
    private times:Array<number>;
    private win:any;
    private timeEnd:any;


    constructor(private el: ElementRef, private winA: WindowService) {
        console.log("time");

        this.running = false;
        this.time = -1;
        this.results = [];
        this.laps = [];
        this.times = [0, 0, 0];
        this.win = window;
        this.timeEnd = performance;

    }

    ngOnDestroy() {
        this.winA.alert("no please");
    }
    public reset() {
        this.times = [0,0,0];
    }

    public stop() {
        this.running = false;
        this.time = -1;
    }

    public start() {
        if(this.time === -1) {
            this.time = this.timeEnd.now();
        }
         if(this.running == false) {

            this.running = true;
            requestAnimationFrame(this.step.bind(this));
        }
    }

    public step(timestamp:any) {
        if(this.running == false) {
            return;
        }
        this.calculate(timestamp);
        this.time = timestamp;
        this.print();
        requestAnimationFrame(this.step.bind(this));
    }

    public calculate(timestamp:any) {
        let diff = timestamp - this.time;

        this.times[2] += diff / 10;

        if (this.times[2] >= 100) {
            this.times[1] += 1;
            this.times[2] -= 100;
        }

        if (this.times[1] >= 60) {
            this.times[0] += 1;
            this.times[1] -= 60;
        }
    }

    public print() {
        let elSpan = this.el.nativeElement.querySelector('span');
        elSpan.innerHTML = this.times;

    }
}
FutureMode
  • 113
  • 1
  • 8

2 Answers2

4

You should use a service using @Injectable then you will be able to navigate different routes and still have the stopwatch counting.

Here is a plunker example: https://embed.plnkr.co/mKThXNaMIlBUMlkXwjr5/

J J B
  • 8,540
  • 1
  • 28
  • 42
0

Why dont you put your Component in one of the parent components and just hide or show it if the app is in your desired state.(No need to specify special route for it).

Lucy
  • 1