敲除更改事件更新数据集时的触发(相关下拉列表)

时间:2016-02-15 14:15:07

标签: javascript jquery knockout.js

我希望这只是我的一个修剪,但是当我不想要它时,我遇到了改变事件的麻烦。我会尽量保持简洁明快。

我有两个下降,国家和城市。这两个都绑定如下:

<select data-bind="options: Countries, event: { change: IChanged }, value: CountrySelected">
<select data-bind="options: Cities, event: { change: IChanged }, value: CitySelected">

我的小视图模型

self.Countries = ko.observableArray([]);
self.Cities = ko.observableArray([]);
self.CountrySelected = ko.observable();
self.CitySelected = ko.observable();

现在我的功能IChanged()

self.IChanged = function(item) {
    GoGetMyOptions().done(function(response) {
        self.Cities(response);    
    });
}

问题!

调用self.Cities(response);时会触发City下拉列表中的更改事件,这意味着下拉列表会再次调用该方法。

买者

我简化了这个,我可以有1到80个过滤器。在我的代码中,我基本上会在右边的所有内容中加载下拉选项,问题是它是否为右边的所有内容调用了更改事件:O Ideas any?

一个更复杂的例子(更接近我的代码

我实际上有一个过滤器集合self.FilterCollection,每个过滤器都有以下内容:

self.DropDownValues = ko.observableArray([]);
self.SelectedValue = ko.observable();

您可以看到,当选择下拉菜单时,它会更新所选值,然后刷新右侧所有过滤器的DropDownValues数组。

在一个相当尴尬的场景中,

  1. 用户已选择城市
  2. 他们选择一个国家
  3. CITY列表更新
  4. 因此重置当前值**
  5. 第4号将触发我相信的订阅......

    完整场景

    有4个下降,A,B,C和D.

    当用户从A中选择一个值时,我将遍历剩余的下拉列表并调用getValues,这将更新DropDownValues可观察量。

    因此,我希望, 1 用户界面事件触发说&#34;用户更改下拉a&#34;,然后我需要进行 3 ajax调用加载B,C和D并更新可观察数组。

    我的问题是,当用户选择A时,它会正确地进行3次ajax调用,但在设置B的值时会触发事件......

    这意味着B将进行2次ajax调用以更新C和D.因此,当用户选择下拉A中的某些内容时,它实际上会触发:

    1个UI事件,3个Ajax调用,1个UI事件,2个ajax调用,1个UI事件,1个ajax调用,然后是一个最终的UI事件。因此,要进行sumarize,用户单击一下就可以进行4次UI事件调用和6次ajax调用:(

1 个答案:

答案 0 :(得分:0)

我有一种直觉感觉你过于简单地提出这个问题,但就目前而言,关于你的复制品有两点要点:

  1. 您正在订阅 DOM 事件。不需要:改为使用基于视图模型的订阅。它会为您提供更多控制权,并允许您对其进行单元测试。
  2. 您在更改IChanged下拉列表时调用了Cities,这没有任何意义。为什么在用户更改该城市时更新可用城市列表?
  3. 无论如何,这是一种阻止循环更新的方法:

    function GoGetMyOptions(country) {
      console.log("Doing ajaxy stuff");
      return {
        done: function(callback) {
          if (country === "USA") callback(["New York", "L.A.", "Chicago"]);
          if (country === "GBR") callback(["London", "Manchester", "Leeds"]);
          if (country === "GER") callback(["Bonn", "Koln", "Hamburg"]);
        }
      };
    }
    
    function ViewModel() {
      var self = this;
    
      self.Countries = ko.observableArray([]);
      self.Cities = ko.observableArray([]);
      self.CountrySelected = ko.observable();
      self.CitySelected = ko.observable();
      
      self.CountrySelected.subscribe(function(newVal) {
        GoGetMyOptions(newVal).done(function(response) {
          self.Cities(response);
        });
      });
    
    }
    
    var vm = new ViewModel();
    
    vm.Countries.push("USA", "GBR", "GER");
    
    ko.applyBindings(vm);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
    
    <select data-bind="options: Countries, value: CountrySelected"></select>
    <select data-bind="options: Cities, value: CitySelected"></select>

    正如您在控制台上看到的那样,只有在更改国家/地区时才会更改城市时发生Ajax调用。