gpt4 book ai didi

javascript - 更新数据集时触发 knockout 更改事件(相关下拉列表)

转载 作者:行者123 更新时间:2023-11-28 06:22:21 25 4
gpt4 key购买 nike

我希望这只是我的一点 trim ,但当我不希望更改事件触发时,我遇到了麻烦。我会尽量保持简短和清晰。

我有两个下拉菜单:国家/地区和城市。两者的绑定(bind)如下:

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

我的小 View 模型

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);时,它会触发城市下拉菜单上的更改事件,这意味着下拉菜单将再次调用该方法。

警告

我已经简化了这个,我可以有 1 到 80 个过滤器。在我的代码中,我基本上开始加载右侧所有内容的下拉选项,问题是它调用右侧所有内容的更改事件:O 有人有想法吗?

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

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

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

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

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

  1. 用户选择了一个城市
  2. 他们选择一个国家/地区
  3. 城市列表已更新
  4. 从而重置当前值**

我相信第 4 号将触发订阅...

完整场景

有 4 个下拉菜单:A、B、C 和 D。

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

因此,我希望 1 UI 事件触发,说“用户更改了下拉菜单 a”,然后我需要进行 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 调用,然后是 1 个最终 UI 事件。总而言之,用户单击一次会进行 4 个 UI 事件调用和 6 个 ajax 调用:(

最佳答案

我有一种直觉,你问这个问题过于简单化了,但就目前情况而言,关于你的重现,有两点需要说明:

  1. 您正在订阅 DOM 事件。不需要这样做:改用基于 View 模型的订阅。它会给您更多的控制权,并允许您对其进行单元测试。
  2. 您在更改 Cities 下拉列表时调用 IChanged,这是没有意义的。为什么当用户更改城市时要更新可用城市列表?

无论如何,这里有一个防止循环更新的方法:

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 调用,只有更改国家/地区时才会发生。

关于javascript - 更新数据集时触发 knockout 更改事件(相关下拉列表),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35411664/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com