使用ASP.NET和KnockoutJS从另一个组合框填充一个



我知道以前有人问过它,但我已经问了几个小时了,找不到可行的解决方案。总结一下,我从服务器(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);
        }
    });
};

香草味十足,对吧?locationsList的每个条目都由一个字符串组成,该字符串是一个州和另一个列表,该列表由该给定州的城市组成。我对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提供的一组新选项很麻烦。

我想你可能会对Knockout的工作原理感到困惑,它可能有助于通过turorials。你似乎在做两件违背KO理念的事情,这也是你问题的一部分:

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

此外,您还需要:

  • CCD_ 4绑定以将可观察到的绑定到所选状态

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

<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);
            });
        }
    });
});

这里有一把小提琴来演示它是如何工作的。

最新更新