2

我有以下淘汰视图模型:

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操作,有时它是设置的,但其他的它是未定义的。

4

2 回答 2

2

您不必进行单独的 ajax 调用,而是必须链接这些 ajax 调用,以确保在您的 deparmantArray 中始终存在有效的 deparmantList 对于任何给定的 id。因为 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延迟对象

编辑:

就像 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);

});
于 2012-08-22T13:37:33.930 回答
0

Knockout 会尝试强制您根据当前选项做出有效选择。听起来有时您对所选部门的 AJAX 请求会在部门列表之前返回。在这种情况下,所选部门实际上不在部门列表中。

一些选项:

  • 找到一种方法来发出单个请求,返回您需要的所有数据
  • 如果尚未填充部门,请在您的选项中添加一个虚拟条目。就像是:

    success: function (data) {
        if (!self.departments().length) {
            self.departments.push(data);
        }
        self.selectedDepartment(data.DepartmentId);
    }
    

然后当部门进来时,他们可以覆盖这个虚拟条目。

于 2012-08-22T12:38:53.443 回答