2

谁能告诉我在以下代码中执行从淘汰赛到 .net WebAPI 的三个单独获取请求以绑定可观察数组的最佳方法?Firebug 显示加载时间为几毫秒,但实际上需要几秒钟。

在查看任何 javascript async 之前,我希望能得到一些指导。

   $(function () { 
        var model = new viewModel();
        model.todayTimes([]); 
        model.zones([]);
        model.dayTypes([]);

        $.get('../api/Zone', function (data) {
        model.zones(data);

        });

         $.get('../api/DayType', function (data) {
        model.dayTypes(data);

        });

        $.get('../api/TemplateTime/?dayTypeId='+model.dayType(), function (data) { 
            model.todayTimes(data); 
            ko.applyBindings(model); 
        }); 

编辑

function viewModel() {
        var self = this;
        self.dayType = ko.observable(1);
         self.todayTimes = ko.observableArray([]);
         self.dayTypes = ko.observableArray([]);
         self.zones = ko.observableArray([]);

//other code

  $.getJSON("/api/Zone", function(data) {
    self.zones(data);


    $.getJSON("/api/DayType", function(data) {
    self.dayTypes(data);
    }); 

       $.getJSON('../api/TemplateTime/?dayTypeId=1', function (data) { 
            self.todayTimes(data); 
        }); 

}
  $(function () { 
        ko.applyBindings(new viewModel());           
      });
4

2 回答 2

2

所以我会先问他们是否需要 3 次调用,因为在页面加载时发出三个单独的 ajax 请求是非常浪费的。几乎可以肯定有更好的方法来做到这一点。另外,这是一次性的,还是需要重复使用?

如果这是一次性的,我不得不想知道为什么会发生这种情况。该数据应由服务器收集并与初始页面请求一起发送。这是最优路径。如何做到这一点取决于您的服务器堆栈,但它们都支持模型序列化为 JSON,您可以在构建期间将其直接转储到您的视图模型中。

如果它需要可重用(这是发出这些 ajax 请求的唯一原因),那么它们真的需要 3 个单独的调用吗?它们看起来是相关的,并且可能会同时请求所有数据。将其组合成可重用的东西可能如下所示:

var ViewModel = function(initialData) {
    var self = this;
    self.dayType = ko.observable(initialData.dayType || []);
    self.todayTimes = ko.observableArray(initialData.todayTimes || []);
    self.dayTypes = ko.observableArray(initialData.dayTypes || []);
    self.zones = ko.observableArray(initialData.zones || []);

    self.getData = function() {
        $.getJSON("/api/timeInfo", function(data) {
            self.todayTimes(data.todayTimes || self.todayTimes()));
            self.dayTypes(data.dayTypes || self.dayTypes()));
            self.zones(data.zones || self.zones()));
        };
    };
};

如果他们真的需要3个单独的电话,你可以分开getData,但同样,只有当它们是真正独立的电话时才这样做。如果您确实拆分它们,我将遵循使它们在视图模型上起作用的模式。这允许它们在外部被调用,并被视图绑定。可重复使用的。

于 2012-07-31T23:55:08.253 回答
0

我同意@Tyrsius 的观点,即您需要将三个请求打包到一个“包装器 API 调用”中以克服延迟问题。

我建议详细说明上述视图模型,以便在内联数据/ ajax 请求数据中更加可重用:

function ViewModel(initialData) {
  // setup properties
  this.dayType = ko.observable();
  this.todayTimes = ko.observable();
  this.dayTypes = ko.observable();
  this.zones = ko.observable();

  if (initialData) {
    this.update(initialData);
  }
}

ViewModel.prototype.update = function(data) {
  data.todayTimes && this.todayTimes(data.todayTimes);
  data.dayTypes && this.dayTypes(data.dayTypes);
  data.zones && this.zones(data.zones);
};

ViewModel.prototype.load = function() {
  $.getJSON('/api/timeInfo', this.update.bind(this));
};

无论如何,在不幸的情况下,您无法创建包装 API 端点,但您想在加载所有必要数据时更新 UI,那么您将无法自拔,只能使用异步支持。

jQuery 为您提供了延迟对象 API,但也有提供并行任务 API的 Async 库,在我看来它可以解决您的问题。

于 2015-01-06T18:53:19.700 回答