用AJAX替换可观察数组

时间:2015-07-08 11:06:08

标签: javascript jquery arrays knockout.js

在我们的应用程序中,我们有一系列选择过滤器,必须根据情境的上下文动态填充。首次加载时,默认选项通过AJAX插入到数组中,并按预期显示在UI上。但是,当选择列表刷新时,即使检查代码,数组似乎包含新值,UI也不会反映更改。

我为两个过滤器编写了相同的代码,但由于一些奇怪的原因它只适用于其中一种情况,我尝试了以下方法来解决这个问题无济于事:

  • 使用任意数据手动填充数组
  • 强制使用array.valueHasMutated()
  • 更新knockout
  • 使用两种不同类型的阵列清除函数array.removeAll和array([])
  • 使用push.apply并按
  • 将结果保存到变量,然后将其分配给数组
  • 使数组内的值可观察

当选项更改时,第一个代码实例按预期工作:

     success: function (data) {
                      self.filtersModel.values2.removeAll();

                      var serverData = $.map(data, function (value, i) {
                               return new SelectBoxOption(value.Description, value.Id);
                      });

                      serverData.forEach(function (value) {
                               self.filtersModel.values2.push(value);
                      }); 
             }

这是第二个不起作用的功能:

     success: function (data) {
                      self.filtersModel.values.removeAll();

                      var other;

                      var serverData = $.map(data, function (value, i) {
                               // If the option is "other" save it as a variable and add to array later
                               if (value.Code === "OTHR") {
                                        other = new SelectBoxOption(value.Description, value.Id);
                                        self.filtersModel.othersValue(value);
                               }
                               else if (value.Code == "EQTY") {
                                        var equity = new SelectBoxOption(value.Description, value.Id);
                                        self.filtersModel.equityValue(value);
                                        return equity;
                               }
                               else
                                        return new SelectBoxOption(value.Description, value.Id);
                      });

                      serverData.forEach(function (value) {
                               self.filtersModel.values.push(value);
                      });

                      // Add "other" option to bottom of the array
                      if (other)
                               self.filtersModel.values.push(other);
             }

非常感谢任何帮助。

更新

填充选择列表的HTML如下所示:

<div class="form-group">
    <label for="value">Value</label>
    <select id="value" class="form-control" data-bind="value: selectedValue, options: values, optionsCaption: '-- ' + 'Select Value' + ' --', optionsValue: 'optionId', optionsText:  'optionName'"></select>
</div>
<div class="form-group">
    <label for="value2">Value 2</label>
    <select id="value2" class="form-control" data-bind="enable: $parent.valueIsAuthorisedAndvalueIsEquityOrOther, value: selectedValue2, options: values2, optionsCaption: '-- ' + 'Select Value 2' + ' --', optionsValue: 'optionId', optionsText:  'optionName'"></select>
</div>

示例数据以以下格式返回:

data = [
    {optionId: 1, optionName: "Value 1"}, 
    {optionId: 2, optionName: "Value 2"},
    {optionId: 3, optionName: "Value 3"}, 
    {optionId: 4, optionName: "Value 4"}
];

2 个答案:

答案 0 :(得分:0)

如果我理解了您的问题,则第二个代码无效,因为您在每次迭代中都会更新self.filtersModel.othersValueself.filtersModel.equityValue

我重写了你的代码,希望它有所帮助:

self.filtersModel.values.removeAll();

var normals = [];
var others = [];
var equities = [];

ko.utils.arrayForEach(data, function (d) {
   if (d.Code === 'OTHR')
      others.push(new SelectBoxOption(d.Description, d.Id);
  else if (d.Code === 'EQTY')
      equities.push(new SelectBoxOption(d.Description, d.Id);
  else 
      normals.push(new SelectBoxOption(d.Description, d.Id);
});

self.filtersModel.values(normals.concat(equities).concat(others));

答案 1 :(得分:0)

经过深思熟虑后,我发现问题与ajax函数无关,而是在更改选择列表之前我定义的错误方法调用:

self.clearFilters = function() {
    self.filtersModel = new createFiltersModel();
}

function createFiltersModel() {
    return {
        values: ko.observableArray([])
    }
};

每次选择列表发生更改时,都会创建一个新的filtersModel实例,因此在进行ajax调用时,对模型的任何更改都会丢失。卫生署!