Knockout: каскадные выпадающие списки, второй выпадающий выбранный текст
.net MVC, C#, KnockoutJS
Итак, у меня есть 2 выпадающих списка. Оба, чьи данные заполняются с помощью Ajax-вызова от нокаута до функции контроллера MVC. Первоначальная настройка работает нормально, когда при выборе первого выпадающего списка заполняется второй. Что мне нужно сделать, это передать текст и значение, выбранное во втором раскрывающемся списке события нажатия кнопки, следующему контроллеру. Я попытался подписаться и onchange, но не могу получить значение и текст, выбранный из второго раскрывающегося списка. Вот код ниже:
Раскрывающийся список 1
<select data-bind="options: countries ,
optionsText: 'Name',
optionsValue: 'ID',
value: selectedCountry,
optionsCaption: '--Please Select--'" asp-placeholder-for="Country" asp-for="Country" class="form-control common-input-text"></select>
Dropdown 2
<select data-bind="options: states ,
optionsText: 'Name',
visible: ifSelected,
optionsValue: 'ID',
event: { change: selectionChanged },
value: selectedState"
asp-placeholder-for="State" asp-for="State"
class="form-control common-input-text"></select>
Нокаут
(function () {
var viewModel = function (vmData) {
var self = this;
self.countries = ko.observableArray();
self.selectedCountry = ko.observable();
self.states = ko.observableArray();
self.ifSelected = ko.observable(false);
self.selectedState = ko.observable();
//Populate Country DDL
$.ajax({
url: rootDir + "/Home/GetCountry",
type: "GET",
contentType: "application/json",
async: false,
success: function (data) {
self.countries(JSON.parse(data));
}
});
//Populate state DDL based on country
self.selectedCountry.subscribe(function (val) {
$.ajax({
url: rootDir + "/Home/GetStates",
type: "GET",
data: { stateVal: val },
contentType: "application/json",
async: false,
success: function (data) {
var jsonData = JSON.parse(data);
self.ifSelected(true);
self.states(jsonData);
}
});
});
//I have tried to subscribe to second dropdown but this function is never hit
self.selectedState.subscribe(function (value) {
});
//I have tried to bind onchange event to state dropdown but the selected value is always null
self.selectionChanged = function(event) {
var a = self.selectedState(); //null or udefined
}
};
var pageVM = new viewModel();
ko.applyBindings(pageVM, $("form")[0]);
})();
1 ответ
Код, который вы разместили, кажется нормальным. "selectedState" содержит идентификатор выбранного элемента. Если вам нужен весь объект, а не только идентификатор, рассмотрите возможность удаления привязки "optionsValue: 'ID'" из раскрывающегося списка состояний.
var viewModel = function(vmData) {
var self = this;
self.countries = ko.observableArray();
self.selectedCountry = ko.observable();
self.states = ko.observableArray();
self.ifSelected = ko.observable(false);
self.selectedState = ko.observable();
//Populate Country DDL
setTimeout(function(data) {
self.countries([{ Name: 'us', ID: 1 }, { Name: 'ca', ID: 2 }, { Name: 'mx', ID: 3 }]);
}, 500);
//Populate state DDL based on country
self.selectedCountry.subscribe(function(val) {
console.log('country changed');
setTimeout(function(data) {
self.ifSelected(true);
self.states([{ Name: 'ca', ID: 1 }, { Name: 'nv', ID: 2 }, { Name: 'tx', ID: 3 }]);
}, 500);
});
//I have tried to subscribe to second dropdown but this function is never hit
self.selectedState.subscribe(function(value) {
console.log('state changed');
});
//I have tried to bind onchange event to state dropdown but the selected value is always null
self.selectionChanged = function(event) {
var a = self.selectedState(); //null or udefined
}
};
var pageVM = new viewModel();
ko.applyBindings(pageVM);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select data-bind="options: countries ,
optionsText: 'Name',
optionsValue: 'ID',
value: selectedCountry,
optionsCaption: '--Please Select--'" asp-placeholder-for="Country" asp-for="Country" class="form-control common-input-text"></select>
<select data-bind="options: states ,
optionsText: 'Name',
visible: ifSelected,
event: { change: selectionChanged },
value: selectedState" asp-placeholder-for="State" asp-for="State" class="form-control common-input-text"></select>
<br/>
selectedState: <span data-bind="text: ko.toJSON(selectedState)"></span>