我有以下的淘汰视图模型:
function DepartmentsViewModel() {
var self = this;
self.currentComplaint = ko.observable('');
self.departments = ko.observableArray([]);
self.selectedDepartment = ko.observable('').extend({
required: true
});
}
然后我填充我的部门并为selectedDepartment
值分配一系列远程调用到我的控制器(id
只是我根据用户当前页面分配给变量的数字):
$(function() {
var self = new DepartmentsViewModel();
self.currentComplaint(id);
$.ajax({
url: '@Url.Action("GetDepartments")',
success: function (data) {
self.departments(data);
}
});
$.ajax({
url: '@Url.Action("GetDetails")',
data: { id: id },
success: function (data) {
self.selectedDepartment(data.DepartmentId);
}
});
ko.applyBindings(self);
});
然后在我的HTML中填充,如下所示:
<select class="complaint-select"
data-bind="options: departments,
optionsText: function(item) {
return item.DepartmentCode + ' - ' + item.DepartmentName
},
optionsValue: 'DepartmentId',
value: selectedDepartment,
optionsCaption: 'Choose..'">
</select>
我注意到,当我刷新页面时,有时我的selectedDepartment
没有设置,因此,我的下拉列表没有设置任何值,并告诉我从下拉列表中选择一个选项?知道为什么?我已经在我的AJAX请求的console.log(self.selectedDepartment());
操作上完成了complete
,有时它已经设置好了,但其他一些是未定义的。
答案 0 :(得分:2)
您不必进行separete ajax调用,而是必须链接这些ajax调用,以确保对于任何给定的id,您的departmantArray中始终存在有效的deparmantList。因为ajax调用的结果是随机的,你无法确定哪一个是第一个。
var departmantLoadProcess = $.ajax({
url: '@Url.Action("GetDepartments")'
});
departmantLoadProcess.done(function(data){
self.departments(data);
var detailLoadProcess = $.ajax({
url: '@Url.Action("GetDetails")',
data: { id: id },
success: function (data) {
}
});
detailLoadProcess.done(function(data){
self.selectedDepartment(data.DepartmentId);
});
});
有关更多信息,请检查Jquery deferred object
修改强>
就像Ryan提到的那样,如果我们获得数百万的命中率,那么ajax请求会导致一些超载:)如果他们的结果不依赖于彼此,我们就不需要等待它们。我们可以进一步优化它。
// If both ajax request success
$.when( $.ajax({url: '@Url.Action("GetDepartments")'}),
$.ajax({url: '@Url.Action("GetDetails")' , data : {id:id}}) ).done(function(deparmantsData,detailsData) {
self.departments(deparmantsData);
self.selectedDepartment(detailsData.DepartmentId);
});
答案 1 :(得分:0)
Knockout尝试强制您根据当前选项进行了有效选择。听起来有时候您所选部门的AJAX请求会在部门列表之前返回。在这种情况下,所选部门实际上并不在部门列表中。
一些选项:
如果尚未填充部门,请在选项中添加虚拟条目。类似的东西:
success: function (data) {
if (!self.departments().length) {
self.departments.push(data);
}
self.selectedDepartment(data.DepartmentId);
}
然后当部门进来时,他们可以覆盖这个虚拟条目。