2

我有一个完全使用 Knockout 创建的页面。在其中一个模板中,单击一个链接将显示一个 JQuery Datepicker 控件以选择一个日期。选择日期后,将使用所选日期执行功能,并且 Datepicker 关闭。这么多工作就好了。

从有人选择日期到 Datepicker 关闭可能需要几秒钟的时间。这是由于一个名为 (LoadAppointmentTimeSlots) 的函数需要同步运行并且可能需要一段时间才能完成它的工作。为了解决这个问题,我希望出现一个 DIV,向用户提供系统正在运行的反馈(“#loading”)。

问题是 DIV 直到 LoadAppointmentTimeSlots 函数执行后才会出现(此时 DIV 再次被隐藏)。我已经以多种方式尝试了 setTimeout,但没有任何效果。

以下是“违规”代码:

var SchedulingViewModel = function () {
  var self = this;
  ...
  self.Date_OnClick = function () {
    var selectedDate;
    $("#calendarPopup").append('<div  id="datepicker" />');
    $("#datepicker").datepicker({
      dateformat: 'mm-dd-yy',
      changeMonth: true,
      changeYear: true,
      setDate: new Date(),
      minDate: 0,
      maxDate: self.SelectedRFVInterval() - 1,
      onSelect: function (datetext, inst) {
        selectedDate = datetext;
        $("#loading").show();
        self.LoadAppointmentTimeSlots(datetext);  // function within view model that                 uses $AJAX in sync mode to return time slot data
        $("#loading").hide();
        $('#calendarPopup').dialog('close');
      }
    });
  };
  ...
}
4

1 回答 1

1

您遇到的困难是因为 show() 是异步执行的,并且由于 javascript 在单个线程中执行,这意味着它们必须等到所有同步代码(例如 LoadAppointmentTimeSlots)完成。

要获得您想要的行为,请将 show() 调用之后的所有内容放入 show 命令的回调中。这样 LoadAppointmentTimeSlots 在 show() 调用完成之前不会执行。方法如下:

// ... other code
$("#loading").show(function() {
    self.LoadAppointmentTimeSlots(datetext);  
    $("#loading").hide();
    $('#calendarPopup').dialog('close');
});

但是,最好将 LoadAppointmentTimeSlots 中的 ajax 调用更改为异步调用,并将 hide() 和 dialog('close') 调用移至 ajax 调用的回调。这允许 javascript 在您等待 LoadAppointmentTimeSlots 完成时继续执行其他操作。这可能看起来更像这样:

// ... other code
$("#loading").show()
self.LoadAppointmentTimeSlots(datetext, function() {
    $("#loading").hide();
    $('#calendarPopup').dialog('close');
});
// ... more code


function LoadAppointmentTimeSlots(datetext, alwaysCallback) {
    // Prepare request details
    $.ajax( "/myendpoint?param=foo" )
      .done(function(data) { alert("success"); }) // do something with data 
      .fail(function() { alert("error"); })
      .always(alwaysCallback); // called on both success and failure of ajax call
}
于 2012-12-09T01:58:27.400 回答