Не работает привязка отдельных параметров с проверкой jQuery - PullRequest
9 голосов
/ 19 июля 2011

Я связываю список объектов с select, используя нокаут.Класс объекта может иметь любое количество свойств

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

. Это прекрасно работает, и я могу использовать viewModel.selectedCity().Name или viewModel.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

Вот мой Object Watch на selectedCity:

viewModel.selectedCity() in watch returns an object

Вот Object Watch на selectedCity, когда указано optionsValue:

With OptionsValue

Ответы [ 4 ]

8 голосов
/ 21 июля 2011

Проблема в том, что при работе с объектами в качестве значения элементам option присваивается значение "". Проверка JQuery не проходит из-за этого. Вы можете написать привязку или привязку обертки к привязке options, которая проходит и просто устанавливает для нее значение, но я не думаю, что предпочтительнее идти по этому пути.

Достойным вариантом является сохранение значения и использование зависящего от объекта наблюдения для представления выбранного в данный момент объекта.

Это было бы как:

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/

6 голосов
/ 02 октября 2014

Довольно аккуратным решением было бы добавить параметр optionsAfrerRender к привязке опций.Предполагая, что в объекте selectedCity есть поле cityId, вы можете присвоить ему значение опции.Пожалуйста, проверьте следующее решение на основе вашего примера:

 <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 голосов
/ 14 мая 2016

Приведенный выше ответ работает с одной оговоркой. Первая граница выбранного значения («--select the city--») будет неопределенной, что приведет к ошибке.

Если вы измените код для обработки, он будет работать.

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

Примечание: для краткости я удалил все из ViewModel, кроме метода setOptionValue.

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

0 голосов
/ 06 сентября 2016

Чтобы расширить ответ Роберта, мы можем заставить вспомогательную функцию работать для каждого раскрывающегося списка в модели представления независимо от привязки данных к контексту, позволяя пользователю передать строку для правильного свойства:

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>
...