2014-09-16 4 views
0

В моей модели у меня есть массив объектов с наблюдаемыми элементами. У меня есть подписка на один из этих элементов (выпадающий список), чтобы заполнить следующий раскрывающийся список (каскадные выпадающие списки). Теперь мне нужно получить описание выбранного значения в этих выпадающих меню. Как бы я вытащил это значение из выпадающего списка? Я стараюсь избегать запуска запроса на сервере, если это возможно.Как определить, какой элемент DOM соответствует элементам наблюдаемого массива Knockout?

В прошлом я сделал self.deptName($('#AssignedDepartment option:selected').text());, но теперь это выпадающее меню не уникально. У меня было бы много выбора. Я использую uniqueName: true в каждом из полей. Как в пределах подписки я могу определить, какая выпадающая группа изменилась?

Вот то, что мой подписываться выглядит как:

// Build the hours types when the request type is selected 
    self.RequestType.subscribe(function (newValue) { 
     FindRequestType(newValue, function (record) { 
      // Do stuff 
     }); 
    }); 

Вот HTML для выпадающего списка:

<select class="required span12" data-bind="leaveTypeDropDown: RequestType, uniqueName: true"></select> 

Вот bindingHandler:

ko.bindingHandlers.leaveTypeDropDown = { 
    init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     // If we don't have the leave request dropdown data, pull it. 
     if (jsonRequestType === "") { 
      $.ajax({ 
       'async': false, 
       'url': '/api/payroll/LeaveRequestTypes/', 
       'dataType': 'text json', 
       'type': 'GET', 
       'success': function (json) { 
        jsonRequestType = json; 
        jsonRequestTypeRecieved = true; 
       } 
      }); 
     } 

     // Fill the drop down list. 
     LoadRequestType(element); 

     // register event handler where bound observable will be changed 
     ko.utils.registerEventHandler(element, 'change', function() { 
      var observable = valueAccessor(); 
      observable(element.value); 
     }); 

     // Select the value from the previous record if there is one. 
     if (selectedRequestType !== null) { 
      element.value = selectedRequestType; 
      ko.utils.triggerEvent(element, 'change'); 
      selectedRequestType = null; 
     } 
    } 
}; 

Update 1: Потому что есть путаница. Если я выберу значение «VAC» с текстом «Отпуск» в раскрывающемся списке. Как получить текст «Отпуск» в моей модели?

Обновление 2: Вот jsFiddle с моим (главным образом) рабочим кодом, указанным выше. http://jsfiddle.net/MikeWills/cykuqxto/6/ По какой-то причине при загрузке мои капли не работают, но добавьте еще один день, и вы увидите мои рабочие выпадающие списки.

+0

Это зависит от того, как вы связываете выпадающий список с нокаутом. Ваш self.RequestType будет получать контекст и значение, переданное подписке. Если вы обновите свой пример кода, чтобы показать свой HTML, было бы легче помочь. Упреждающе, я бы предположил, что вы должны это проверить, если вы этого не сделали: http://knockoutjs.com/documentation/options-binding.html – Milimetric

+0

@Milimetric добавил, что HMTL –

+0

Вы пишете вопрос «Как в пределах подписаться, я определяю, какой выпадающий список изменился? " и я бы сказал, что с мышлением MVVM вы не должны. Модели представления должны иметь данные, представление представляет собой пользовательский интерфейс для моделей view. Представление знает о viewmodel, viewmodel не должен знать вид. Вы также спрашиваете: «Как я могу вытащить это значение [description] из выпадающего списка?» и ответ будет заключаться в том, что вы вытаскиваете его из viewmodel, а не в раскрывающийся список. Но я предполагаю, что я просто не понимаю, о чем вы действительно спрашиваете. Не могли бы вы прояснить свой вопрос? –

ответ

1

Нам нужно немного почистить ваш подход. Во-первых, давайте сделаем все наблюдаемые нам нужны на вашей модели и заполнить первый выпадающий выбор с помощью Ajax вызова:

var viewModel = { 
    firstDropDownOptions: ko.observableArray(), 
    firstDropDownChoice: ko.observable() 
}; 

$.ajax(...).done(function (data) { 
    // process data and assign 
    // for the binding below to work, processedData has to have items like this: 
    // {textProperty: 'some text', otherProperty: ...} 
    // as you said in a comment, you have option groups so I'm going to assume 
    // processedData looks like this overall: 
    // [{group: 'one', options: [{text: 'Vacation', value: 'VAC'}, ...]}, ...] 
    viewModel.firstDropDownOptions(processedData); 
}); 

Тогда давайте связать, что наблюдаемое в вашей ниспадающего с помощью options binding:  

<select data-bind="foreach: firstDropDownOptions, value: firstDropDownChoice"> 
    <optgroup data-bind="attr: {label: label}, foreach: options"> 
     <option data-bind="text: text, option: $data"></option> 
    </optgroup> 
</select> 

Это использует пользовательские привязки из KnockoutJS - Binding value of select with optgroup and javascript objects:

ko.bindingHandlers.option = { 
    update: function(element, valueAccessor) { 
     var value = ko.utils.unwrapObservable(valueAccessor()); 
     ko.selectExtensions.writeValue(element, value); // note this is magic 
    }   
}; 

Наконец, давайте подписываться на наблюдаемую, что мониторы изменения в этом первом раскрывающемся списке:

viewModel.firstDropDownChoice.subscribe(function (newChoice) { 
    // in this function, newChoice is the option selected in the first drop down, 
    // but not just the value, the whole object, so you can do: 
    console.log(newChoice, newChoice.text); 
}); 
+0

Проблема с этим для моего раскрывающегося списка заключается в том, что я использую группы опций в своем раскрывающемся списке для удобства использования. Так что в этом случае это не сработает. Но я буду помнить это для будущих времен, когда я работаю с выпадающими списками. Я добавил jsFiddle, что, по крайней мере, показывает, что я делаю, хотя это немного багги. –

+0

Тот же принцип применяется, хотя, если у вас есть группы параметров, вам придется вручную привязать свои варианты. Я обновлю код выше. – Milimetric

+0

Я обновил, ключ использовал специальную привязку параметров, чтобы убедиться, что выбранный вами элемент является полным объектом, а не только одним из свойств параметра, который вы связываете. – Milimetric

Смежные вопросы