2016-07-20 3 views
0

Я пытаюсь заполнить значение по умолчанию для зависимого выпадающего списка, используя нокаут.Выпадающий каскад выпадающего списка не обновляется

Когда значения закодированы, они работают, но мне нужно получить значения из запроса ajax, а затем второй вариант выпадающего меню не обновляется. Значение self.selectedState обновляется, но я предполагаю, что, поскольку у меня еще нет заполненных опций, тогда значение в select не связывается. Это мой код до сих пор:

function myViewModel(country, state) { 
 
\t var self = this; 
 
    self.selectedCountry = ko.observable(); 
 
\t self.selectedState = ko.observable(); 
 
    
 
    self.availableCountries = ko.observableArray([ 
 
    \t { 
 
    \t \t id: 1, name: 'United States', states: [ 
 
\t \t \t \t { id: 1, name: 'Alabama' }, 
 
     { id: 2, name: 'California' }, 
 
\t \t \t ] 
 
\t \t }, 
 
\t \t { 
 
\t \t \t id: 2, name: 'Canada', states: [ 
 
\t \t \t \t { id: 53, name: 'Alberta' }, 
 
\t \t \t ] 
 
\t \t } 
 
\t ]); 
 
    
 
    self.availableStates = ko.observableArray([]); 
 
\t 
 
    self.selectedCountry.subscribe(function() { 
 
\t \t self.availableStates([]); 
 
    
 
\t \t for (var i = 0; i < self.availableCountries().length; i++) { 
 
\t \t \t if (self.availableCountries()[i].id == self.selectedCountry()) { 
 
\t \t \t \t self.availableStates(self.availableCountries()[i].states); 
 
\t \t \t \t break; 
 
\t \t \t } 
 
\t \t } 
 
\t }); 
 
    
 
    self.selectedCountry(1).selectedState(2); 
 
} 
 

 
var viewModel = new myViewModel(); 
 
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<select data-bind="options: availableCountries, optionsText: 'name', optionsValue: 'id', optionsCaption: 'Select a country...', 
 
value: selectedCountry"></select> 
 

 
<select data-bind="options: availableStates, optionsText: 'name',optionsValue: 'id', value: selectedState, visible: availableStates().length > 0" style="display:none"></select>

Есть ли что-то особенное, что должно быть сделано, когда параметры получаются из AJAX?

jsfiddle

ответ

1

Вопрос не AJAX, в частности, но тот факт, что self.selectedState Безразлично» t имеет соответствующее значение option в течение некоторого времени (в то время как параметры выбираются). От the docs:

Обычно, когда вы используете value связывания на <select> элемента, это означает, что вы хотите, ассоциированная модель значение для описания какой элемент в <select> выбран. Но что произойдет, если вы зададите значение модели тому, что не имеет соответствующей записи в списке? Поведение по умолчанию - для нокаута, чтобы перезаписать значение вашей модели до , сбросить его до того, что уже выбрано в раскрывающемся списке, таким образом не позволяет модели и пользовательскому интерфейсу выйти из синхронизации.

Однако иногда вы можете не хотеть этого поведения. Если вместо этого вы хотите, чтобы нокаут позволял вашей модели наблюдать значения, которые имеют , нет соответствующей записи в <select>, затем укажите valueAllowUnset: true. В этом случае всякий раз, когда ваше значение модели не может быть представлено в <select>, тогда <select> просто не имеет выбранного значения при этом времени, которое визуально представляет его как пустое.

+0

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

0

Это прекрасная возможность использовать вычисляемый наблюдаемым. Вычисление, по-видимому, подходит для этой работы, потому что это избавит вас от необходимости настраивать собственные подписки на русификацию в зависимости от треков. Дайте ему попробовать - я изменил очень немного кода, чтобы сделать это ..

function myViewModel(country, state) { 
 
    var self = this; 
 
    self.selectedCountry = ko.observable(); 
 
    self.selectedState = ko.observable(); 
 

 
    self.availableCountries = ko.observableArray([{ 
 
    id: 1, 
 
    name: 'United States', 
 
    states: [{ id: 1, name: 'Alabama' }, 
 
      { id: 2, name: 'California' }, ] 
 
    }, 
 
    { id: 2, 
 
     name: 'Canada', 
 
     states: [{ id: 53, name: 'Alberta' }, ] 
 
    }]); 
 

 
    self.availableStates = ko.computed(function() { 
 
    var states = []; 
 
    for (var i = 0; i < self.availableCountries().length; i++) { 
 
     if (self.availableCountries()[i].id == self.selectedCountry()) { 
 
     states = states.concat(self.availableCountries()[i].states); 
 
     break; 
 
     } 
 
    } 
 
    return states; 
 
    }); 
 

 
    self.selectedCountry(1).selectedState(2); 
 
} 
 

 
var viewModel = new myViewModel(); 
 
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<select data-bind="options: availableCountries, optionsText: 'name', optionsValue: 'id', optionsCaption: 'Select a country...', 
 
value: selectedCountry"></select> 
 

 
<select data-bind="options: availableStates, optionsText: 'name',optionsValue: 'id', value: selectedState, visible: availableStates().length > 0" style="display:none"></select>

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