【问题标题】:Refresh label countdown in NativeScript and Angular在 NativeScript 和 Angular 中刷新标签倒计时
【发布时间】:2016-12-01 13:25:41
【问题描述】:

我正在构建一个计时器倒计时组件,代码如下:

@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,将模板更改为“[text]='timeRemaining'”,但从未显示。

此组件由用户动态添加(与this post 相关)。问题是,当我单击“+”按钮添加新计时器时,时间会显示几分之一秒,然后再次消失。有人知道发生了什么或我做错了什么吗?

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

@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;
    }
}

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

【问题讨论】:

    标签: angular typescript nativescript angular2-nativescript


    【解决方案1】:

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

    区域回调

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

    【讨论】:

    • 感谢您的回复,但这些都对我有用,使用带有异步管道的可观察对象或 ZonedCallback 不会显示任何内容。如果我使用 NgZone,计时器会出现,但不要刷新,并且如果我添加一个新计时器,之前的计时器就会消失,并且不会显示新计时器。
    【解决方案2】:

    你失去了上下文。在 getTimeRemaining(this) 中使用“this”将上下文传递给方法。

    【讨论】:

      猜你喜欢
      • 2012-03-02
      • 1970-01-01
      • 1970-01-01
      • 2016-12-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-04
      • 1970-01-01
      相关资源
      最近更新 更多