任何人都可以告诉我从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());
});
答案 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,在我看来可以解决您的问题。