javascript - Ionic 3 typescript cordova DateTimePicker代码反向运行

标签 javascript cordova typescript ionic-framework datepicker

对于学校,我们必须制作一个可用的恒温器应用程序(这是关于设计的,但仍然需要能够与服务器交互)。我们决定在 ionic 3 中做到这一点。到目前为止,我的道路远非一帆风顺,但这个问题确实让我很困扰。用于选择特定的开启和关闭时间(您需要能够设置多个)。我正在使用标准的 DatePicker,但它的代码似乎是反向运行的..而且我不知道到底是谁在这样做。

完整的代码如下,但我遇到问题的函数是 setNewTime() 这似乎是反向运行的。现在该函数如下所示:

setNewTime() {
this.newTimes = [];
this.timePicker('Day');
this.timePicker('Night');
console.log(this.newTimes);
}

现在奇怪的是,当单击运行此功能的按钮时。首先,它会记录一个空的 newTimes,之后它会使用时间选择器请求夜间时间,然后它会请求白天时间.. 在我看来,这真的很奇怪。首先,我有两个独立的 timePicker 函数。一个用于白天,一个用于晚上,但它们的行为完全相同。我的其余代码似乎运行得很好,而且也是我想要的,但这一部分似乎有它自己的想法。

有人能帮我吗?

鲁本

完整代码:

import { Component } from '@angular/core';
import { DatePicker } from '@ionic-native/date-picker';
import { AlertController } from 'ionic-angular';
import { API } from '../../api';
import { ActionSheetController } from 'ionic-angular';

@Component({
  selector: 'page-monday',
  templateUrl: 'monday.html'
})
export class MondayPage {

  // Variables for get and put
  public day : string = 'day';
  public current_day : string = 'current_day';
  public time : string = 'time';
  public weekProgramState : string = 'weekProgramState';
  public currentTemperature : string = 'currentTemperature';
  public current_temperature : string = 'current_temperature';
  public targetTemperature : string = 'targetTemperature';
  public target_temperature : string = 'target_temperature';
  public dayTemperature : string = 'dayTemperature';
  public day_temperature : string = 'day_temperature';
  public nightTemperature : string = 'nightTemperature';
  public night_temperature : string = 'night_temperature';

  // Arrays for pushing the data
  newTimes: any = [];
  currentPeriods: any = [];
  sparePeriods: any = [];

  constructor(
    private datePicker: DatePicker,
    public alertCtrl: AlertController,
    public api: API,
    public actionSheetCtrl: ActionSheetController
  ) {
    this.getPeriods();
  }

  // Add a new time to the schedule
  setNewTime() {
    this.newTimes = [];
    this.timePicker('Day');
    this.timePicker('Night');
    console.log(this.newTimes);
  }

  // Timepicker that lets you set the time
  timePicker(time) {
    this.datePicker.show({
      date: new Date(),
      mode: 'time',
      //titleText: 'Please pick a ' + time + ' time',
      okText: 'Set ' + time + ' time',
      minuteInterval: 5,
      is24Hour: true,
      androidTheme: 16974393
    }).then(
      date => {
        let minutes = date.getMinutes();
        let hours = date.getHours();
        let time : string;

        if ( hours < 10 ) {
          time = '0' + String(hours);
        } else {
          time = String(hours);
        }

        if ( minutes < 10 ) {
          time = time + ':0' + String(minutes);
        } else {
          time = time + ':' + String(minutes);
        }

        //console.log(time)

        this.newTimes.push(time);
        console.log(this.newTimes)
      },
      err => this.alert(err) //this.newTimes.push(err)
    );
  }

  // Makes sure the times are for format 00:00
  setTime(date) {
    let minutes = date.getMinutes();
    let hours = date.getHours();
    let time : string;

    if ( hours < 10 ) {
      time = '0' + String(hours);
    } else {
      time = String(hours);
    }

    if ( minutes < 10 ) {
      time = time + ':0' + String(minutes);
    } else {
      time = time + ':' + String(minutes);
    }

    console.log(time)

    this.newTimes.push(time);
  }

  // Push an alert out
  alert(typeOfAlert : string) {
    let cancel: string = 'CANCEL';
    if (typeOfAlert == cancel) {
      return;
    } else {
      let alert = this.alertCtrl.create({
        title: 'Error occured!',
        subTitle: 'For some reason an error occured while picking the time. Please try again!',
        buttons: ['OK']
      });
      alert.present();
    }
  }

  // Options for a set time period (change, delete)
  optionsPeriod(id) {
    let actionSheet = this.actionSheetCtrl.create({
      title: 'Modify this time period',
      buttons: [
        {
          text: 'Change',
          handler: () => {
            //this.newTimes = [];
            this.timePicker('night');
            this.timePicker('day');
            this.removeTimePeriod('Monday', this.currentPeriods.indexOf(id));
            this.addTimePeriod('Monday', this.newTimes[0], this.newTimes[1]);
          }
        },{
          text: 'Delete',
          handler: () => {
            this.removeTimePeriod('Monday', this.currentPeriods.indexOf(id));
          }
        },{
          text: 'Cancel',
          role: 'cancel',
          handler: () => {
          }
        }
      ]
    });
    actionSheet.present();
  }

  // Get data from the server
  getServer(tag) {
    return this.api.get(tag);
  }

  // Push data to the server
  putServer(tag, xmlTag, value) {
    this.api.put(tag, xmlTag, value);
  }

  // Add a time period
  addTimePeriod(day, start, end) {
    this.api.addPeriod(day, start, end);
  }

  // Remove a time period
  removeTimePeriod(day, id) {
    this.api.removePeriod(day, id);
  }

  // Gets the current periods and adds empty ones depending on that number.
  getPeriods() {
    this.currentPeriods = [];
    this.sparePeriods = [];
    this.currentPeriods = this.api.getWeekProgram().Monday;
    for(var i = 0; i < (5 - this.currentPeriods.length); i++) {
      this.sparePeriods.push(i);
    }
  }
}

最佳答案

由于函数 datePicker.show() 的异步性质以及函数 timePicker() 的扩展,此行为是预期的。

注意 .then 部分。这意味着 datePicker.show() 返回一个 Promise,该 Promise 会在将来解析并返回一个值。 发生这种情况时,then 部分将异步执行,但在此之前它会被添加到所谓的事件队列中。您可以在视频 What the heck is the event loop anyway? 中了解有关所有这些有趣内容的更多信息。 .

因此,实际发生的情况是,每次调用 timePicker() 时,datePicker.show() 的 .then() 部分都会堆积在事件队列中等待当浏览器的 javacript 引擎无事可做时执行。

确保一切顺利运行的方法是调用 timePicker('Day') 并在其内部的 then() 函数调用 timePicker('Night') >。但要做到这一切,timePicker() 需要返回一个 promise 。

所以我们可以将您的代码更改为如下所示:

// Timepicker that lets you set the time
  timePicker(time) {
    return new Promise( (resolve, reject)  => { // notice I'm wrapping your code with a return of a new Promise
        this.datePicker.show({
        date: new Date(),
        mode: 'time',
        //titleText: 'Please pick a ' + time + ' time',
        okText: 'Set ' + time + ' time',
        minuteInterval: 5,
        is24Hour: true,
        androidTheme: 16974393
        }).then(
        date => {
            let minutes = date.getMinutes();
            let hours = date.getHours();
            let time : string;

            if ( hours < 10 ) {
            time = '0' + String(hours);
            } else {
            time = String(hours);
            }

            if ( minutes < 10 ) {
            time = time + ':0' + String(minutes);
            } else {
            time = time + ':' + String(minutes);
            }

            //console.log(time)

            this.newTimes.push(time);
            console.log(this.newTimes)
        },
        err => window.alert(err) //this.newTimes.push(err)
        );
    });
  }

然后我们可以像这样链接异步函数调用:

  // Add a new time to the schedule
  setNewTime() {
    this.newTimes = [];
    this.timePicker('Day')
        .then(() => {
            this.timePicker('Night')
                .then(() => {
                    console.log(this.newTimes);
                });
        });
  }

你们的学校教授这样的酷炫编码练习真是太棒了,更重要的是你们正在使用 Ionic 和 Angular 等现代框架。坚持下去!

关于javascript - Ionic 3 typescript cordova DateTimePicker代码反向运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44604092/

相关文章:

android - [错误 : Failed to find 'ANDROID_HOME' environment variable. 尝试手动设置

typescript - 在 Protractor 中使用原生 promise

javascript - 在待办事项列表应用中设置更新

ios - 如何将缺少的引用 header 添加到 Cordova IOS 应用程序

javascript - 为什么当我的 javascript 函数返回 false 时我的表单仍然提交?

android - 在 Windows 7 上安装 Phone Gap 时出错

typescript - 为用 Typescript 编写的 Vue 组件生成 d.ts 文件

javascript - 当函数类型为 FunctionalComponent 时,Typescript 返回错误,但箭头函数不返回

javascript - 选择框以更改网址

javascript - 如何将 subview 生命周期责任移至 Marionette