与jQuery验证绑定的单选选项不起作用

时间:2011-07-19 07:42:45

标签: jquery asp.net asp.net-mvc jquery-validate knockout.js

我使用淘汰赛将对象列表绑定到select。对象类可以包含任意数量的属性

<select id="TheProperty_City" 
        name="TheProperty_City" 
        class="required" 
        data-bind="options: cityList, 
                   optionsText: 'Name',  
                   value: selectedCity, 
                   optionsCaption: '--select the city--'" />

这非常合适,我可以使用viewModel.selectedCity().NameviewModel.selectedCity().Value来加载子元素。

我的问题是jQuery验证。如果我保留上述语句,即使在选择之后jQuery也不会重置错误。

我通过在绑定中指定optionsValue来修复它,但是selectedCity返回标量值而不是整个对象。知道如何保留对象行为或以不同方式进行验证吗?

 <select id="TheProperty_City" 
         name="TheProperty_City" 
         class="required" 
         data-bind="options: cityList, 
                    optionsText: 'Name',  
                    optionsValue: 'Value', //added the optionsValue
                    value: selectedCity, 
                    optionsCaption: '--select the city--'" />

如果未指定optionsValue,则错误仍然存​​在:

Without the OptionsValue

这是selectedCity上的对象观察:

viewModel.selectedCity() in watch returns an object

指定selectedCity时,optionsValue上的对象观察是:

With OptionsValue

4 个答案:

答案 0 :(得分:8)

问题在于,当将对象作为值处理时,option元素的值设置为“”。由于这个原因,jQuery验证失败了。您可以编写绑定或包装器绑定到options绑定,并将它们设置为一个值,但我不认为最好走这条路。

一个不错的选择是存储值并使用dependentObservable来表示当前选定的对象。

就像是:

var viewModel = {
    cityList: [{ Name: "Madison", Value: "MSN" }, { Name: "Milwaukee", Value: "MKE" }, { Name: "Green Bay", Value: "GRB" }],
    selectedCityValue: ko.observable()
};

viewModel.selectedCity = ko.dependentObservable(function() {
    var value = this.selectedCityValue();
    return ko.utils.arrayFirst(this.cityList, function(city) {
       return city.Value === value; 
    });
}, viewModel);

使用类似的绑定:

<select id="TheProperty_City" name="TheProperty_City" class="required" 
    data-bind="options: cityList, 
    optionsText: 'Name', 
    optionsValue: 'Value',
    value: selectedCityValue, 
    optionsCaption: '--select the city--'" />

此处示例:http://jsfiddle.net/rniemeyer/EgCM3/

答案 1 :(得分:6)

相当简洁的解决方案是将 optionsAfrerRender 参数添加到选项绑定中。假设选择城市&#39;对象有一个字段&#39; cityId&#39;您可以将其分配给选项值。请根据您的示例检查以下解决方案:

 <select id="TheProperty_City" 
    name="TheProperty_City" 
    class="required" 
    data-bind="options: cityList, 
               optionsText: 'Name',
               value: selectedCity,
               optionsAfterRender: function(option, item) 
                                        { option.value = item.cityId; }
               optionsCaption: '--select the city--'" />

使用这种方法,您将获得敲除选项绑定和jquery验证。

答案 2 :(得分:2)

上述答案有一点需要注意。第一个选择值绑定(&#34; - 选择城市 - &#34;)将是未定义的,从而导致错误。

如果修改代码来处理它,它将起作用。

<select id="TheProperty_City" 
name="TheProperty_City" 
class="required" 
data-bind="options: cityList, 
           optionsText: 'Name',
           value: selectedCity,
           optionsAfterRender: setOptionValue
           optionsCaption: '--select the city--'" />

注意:除了setOptionValue方法之外,我已经从ViewModel中删除了所有内容。

<script type="text/javascript">
var vm = {
    setOptionValue: function(option, item) {
        if (item === undefined) {
            option.value = "";
        } else {
            option.value = item.id;
        }
    }
};
ko.applyBindings(vm);

答案 3 :(得分:0)

为了扩展Robert的答案,我们可以通过允许用户传入正确属性的字符串,使得帮助函数适用于视图模型中的每个下拉列表,无论上下文数据绑定:

<强> JS

self.setOptionValue = function(propId) {
    return function (option, item) {
        if (item === undefined) {
            option.value = "";
        } else {
            option.value = item[propId];
        }
    }
};

<强> HTML

<select class="custom-dropdown" data-bind="options: cityList, 
        optionsAfterRender: setOptionValue('AppointmentTypeId'), value: selectedCityObj, optionsCaption: 'Choose...'" data-validation="required"></select>