刷新NativeScript和Angular中的标签倒计时

时间:2016-12-01 13:25:41

标签: angular typescript nativescript angular2-nativescript

我正在建立一个计时器倒计时组件,这里是代码:

@Component({
  moduleId: module.id,
  selector: 'time-countdown',
  template: `<StackLayout>
                 <Label text="{{timeRemaining}}" ></Label>
             <StackLayout>`
})
export class TimeCountdownComponent implements OnInit {
    @Input() periodDetails  :any; 
    private timeRemaining     :string = "";
    private units           :string = "";

    constructor( private ps: PeriodService) {}

    ngOnInit() {
      this.periodDetails.nextPeriodStartDate = this.ps.getNextPeriod(this.periodDetails);
      console.log("TIME COUNTDOWN: init => " + this.periodDetails.nextPeriodStartDate.toString() )
      setInterval(() => {
          this.getTimeRemaining()
      }, 1000)
    }           

    getTimeRemaining(){
      let trObject = this.ps.getTimeRemaining(this.periodDetails.nextPeriodStartDate);
      this.timeRemaining = trObject.time;
      this.units = (!trObject.units) ? "days": "";
      console.log("TIME COUNTDOWN: Tick => " + this.timeRemaining )
    }          
  }

在控制台中,我得到了正确的单位和剩余时间,但标签中没有显示。我尝试使用Observable.timer()。subscribe,Observable.interval()。subscribe,将模板更改为&#34; [text] =&#39; timeRemaining&#39;&#34;,但从未显示。

此组件由用户动态添加(与this帖子相关)。问题是,当我点击&#34; +&#34;按钮添加一个新的计时器,时间显示一小部分秒,然后再次消失。有人知道发生了什么或我做错了什么?

编辑: 经过大量的研究尝试,如果找到了一个中间解决方案。如果我使用这个组件作为应用程序的根组件,它可以使用这个代码:

@Component({
  moduleId: module.id,
  selector: 'time-countdown',
  template: `
            <StackLayout>
              <Label [text]="timeRemaining | async" ></Label>
            <StackLayout>
            `
})

export class TimeCountdownComponent implements OnInit {
    @Input() periodDetails: any;
    private timeRemaining: any;

    ngOnInit(){
        this.periodDetails.nextPeriodStartDate = this.ps.getNextPeriod(this.periodDetails);
        this.timeRemaining = new Observable<string>((observer: Subscriber<string>) => {
          setInterval(() => observer.next(this.getTimeRemaining().time),1000);
        });
    }


    constructor(private ps: PeriodService ) {}


    getTimeRemaining() {
        let tr = this.ps.getTimeRemaining(this.periodDetails.nextPeriodStartDate);
        console.log(tr.time);
        return tr;
    }
}

但是如果我将它嵌入另一个组件中它不起作用,控制台会显示剩余的时间,但在模板中没有显示任何内容。有人能让我明白发生了什么事吗?

2 个答案:

答案 0 :(得分:0)

如果您使用的是observable,则需要使用异步管<Label [text]="timeRemaining | async" ></Label>,否则可以使用NgZone或zonedCallback

ZoneCallback

declare var zonedCallback: Function;

@Component({
    moduleId: module.id,
    selector: 'time-countdown',
    template: `<StackLayout>
                 <Label text="{{timeRemaining}}" ></Label>
             <StackLayout>`
})
export class TimeCountdownComponent implements OnInit {
    @Input() periodDetails: any;
    private timeRemaining: string = "";
    private units: string = "";

    constructor(private ps: PeriodService) { }

    ngOnInit() {
        this.periodDetails.nextPeriodStartDate = this.ps.getNextPeriod(this.periodDetails);
        console.log("TIME COUNTDOWN: init => " + this.periodDetails.nextPeriodStartDate.toString())
        setInterval(() => {
            this.getTimeRemaining()
        }, 1000)
    }

    getTimeRemaining() {
        let trObject = this.ps.getTimeRemaining(this.periodDetails.nextPeriodStartDate);
        zonedCallback(() => {
            this.timeRemaining = trObject.time;
            this.units = (!trObject.units) ? "days" : "";
        })
        console.log("TIME COUNTDOWN: Tick => " + this.timeRemaining)
    }
}

NgZone

import { NgZone } from "@angular/core";
@Component({
    moduleId: module.id,
    selector: 'time-countdown',
    template: `<StackLayout>
                 <Label text="{{timeRemaining}}" ></Label>
             <StackLayout>`
})
export class TimeCountdownComponent implements OnInit {
    @Input() periodDetails: any;
    private timeRemaining: string = "";
    private units: string = "";

    constructor(private ps: PeriodService, private ngZone: NgZone) { }

    ngOnInit() {
        this.periodDetails.nextPeriodStartDate = this.ps.getNextPeriod(this.periodDetails);
        console.log("TIME COUNTDOWN: init => " + this.periodDetails.nextPeriodStartDate.toString())
        setInterval(() => {
            this.getTimeRemaining()
        }, 1000)
    }

    getTimeRemaining() {
        let trObject = this.ps.getTimeRemaining(this.periodDetails.nextPeriodStartDate);
        this.ngZone.run(() => {
            this.timeRemaining = trObject.time;
            this.units = (!trObject.units) ? "days" : "";
        })
        console.log("TIME COUNTDOWN: Tick => " + this.timeRemaining)
    }
}

答案 1 :(得分:0)

你失去了背景。使用&#34;这个&#34;就像在getTimeRemaining(this)中将上下文传递给方法一样。