0

我知道以前有人问过这个问题,但是我已经研究了几个小时,但找不到可行的解决方案。总而言之,我从服务器(C#)收到一个 JSON 字符串,如下所示:

function CallFromServer() {
$.ajax({
    type: "POST",
    async: false,
    url: "Default.aspx/GetTest",
    data: "{ }",
    contentType: "application/json; charset=utf-8",
    dataType: "json",
    success: function (msg) {
            locationsList = jQuery.parseJSON(msg.d);
        }
    });
};

很香草,对吧?locationList 的每个条目都由一个字符串(一个州)和另一个列表组成,该列表由该给定州的城市组成。我对 KnockoutJS 很陌生(它甚至不是我的项目,我只是做一个小自由职业者),所以在搞砸了一段时间后,我得出了关于如何填充组合框的结论:

HTML:

<select id="stateSelect" onchange="GetCities()" style="background-color:#69bed2; width:50px;" data-placeholder="..."
        data-bind="options: stateValue" name="state" class="chosen-select" tabindex="1">
</select>

<select id="citySelect" style="background-color:#69bed2; width:143px;" data-placeholder="Select a state"
              data-bind="options: cityValue" name="city" class="chosen-select" tabindex="2">
</select>

JS:

function CalculatorViewModel()
{
    var self = this;
    CallFromServer(); //Mine
    GetStates(); //Mine

    self.percentBonus = ko.observable(3);
    self.typedValue = ko.observable("0");
    self.bonusValue = ko.observable('');
    self.messageValue = ko.observable("");
    self.stateValue = ko.observableArray(stateArray); //Mine
    self.cityValue = ko.observableArray(cityArray); //Mine

    (...) //A lot of stuff
}

没有评论为“我的”的东西几乎已经存在,并且随着对 KOJS 文档的一些阅读,我使用它来尝试实现我想要的。

好的,现在让我们了解它的要点。人们可能会注意到我使用了

onchange="GetCities()

在第一个选择中。这是它的代码:

function GetCities() {
    cityArray.clear();
    cityArray[0] = '';
    var currentState = $('#stateSelect :selected').text();
    $.each(locationsList, function (i, e) {
        if (e.stateName == currentState) {
            $.each(e.cityList, function (j, city) {
                cityArray[j] = e.cityList[j].cityName;
            });
        }
    });
};

如预期的那样,只要在状态更改时引发此 onChange 事件,self.cityArray 就会将自身更新为正确的值。但是,无论如何,它所绑定的组合框都不会刷新。我已经阅读了很多关于不同方法的信息,但我觉得我非常接近这种方法,所以从头开始不是一种选择。

有人知道我在这里缺少什么吗?

顺便说一句,不要担心我的 stateArray 绑定,它工作得很好。在选择一个州之后渲染由 cityArray 提供的新选项集被证明是很麻烦的。

4

1 回答 1

2

我认为您可能对 Knockout 的工作原理感到困惑,这可能有助于了解 turorials。您似乎正在做两件事与 KO 的想法背道而驰,这是您问题的一部分:

  • 不要onchange像那样直接连接事件,而是为此使用一些 Knockout 构造(例如订阅);
  • 您似乎正在清除并重新填充可观察数组cityArray而不是cityValue可观察数组;UI 只会响应后者的变化

此外,您还需要:

  • selectedOptions可观察对象绑定到选定状态的绑定

我至少建议按照相应的顺序进行一些更改:

<select id="stateSelect" 
        style="background-color:#69bed2; width:50px;" 
        data-placeholder="..."
        data-bind="options: stateValue, selectedOptions: selectedStates" 
        name="state" 
        class="chosen-select" 
        tabindex="1">
</select>

视图模型需要扩展一些东西来保存状态的选择:

function CalculatorViewModel()
{
    // Added:
    self.selectedStates = ko.observableArray([]);;       
}

同时移除onchange直接事件接线。将其替换为以下内容,订阅 selectedOptions:

// Use a KO subscription:
self.selectedStates .subscribe(function(newStateValue) {

    // Clear the *observable* array
    self.cityValues.removeAll();

    $.each(locationsList, function (i, e) {
        if (e.stateName == newStateValue) {
            $.each(e.cityList, function (j, city) {
                // Push into the observable array so the UI gets updated
                self.cityValues.push(e.cityList[j].cityName);
            });
        }
    });
});

这是一个演示它是如何工作的小提琴。

于 2013-08-19T07:56:13.157 回答