KnockoutJS异步

时间:2012-07-31 23:01:48

标签: knockout.js asp.net-web-api

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

我希望在查看任何javascript异步之前获得一些指导。

   $(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());           
      });

2 个答案:

答案 0 :(得分:2)

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

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

如果它需要可重复使用(这是发出这些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分开,但是,如果他们是真正独立的通话,则只能这样做。如果你拆分它们,我会遵循在viewmodel上使它们成为函数的模式。这允许它们在外部调用,并由视图绑定。可重复使用的。

答案 1 :(得分: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为您提供deferred objects API,但也有Async库提供parallel tasks API,在我看来可以解决您的问题。