Knockout: каскадные выпадающие списки, второй выпадающий выделенный текст

.net MVC, С#, KnockoutJS

Итак, у меня есть 2 выпадающих списка. Оба, данные которых заполняются через вызов Ajax от функции Knockout к функции контроллера 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>

Выпадающий список 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]);
})();

person kaka1234    schedule 01.03.2018    source источник


Ответы (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>

person Jason Spake    schedule 01.03.2018
comment
Джейсон, к сожалению, это не работает. Не знаю, в чем еще проблема на моем конце. Одна вещь, о которой я могу думать, это то, что мои состояния изначально нулевые и заполняются при выборе страны, в которой я делаю вызов ajax. Может ли это быть проблемой. Также моя подписка на состояния вообще не срабатывает при изменении состояния. - person kaka1234; 02.03.2018
comment
@ kaka1234 В рабочем примере, который я опубликовал, состояния также изначально пусты и заполняются через полсекунды таймером, поэтому я не думаю, что проблема в этом. Вы получаете какие-либо ошибки консоли? - person Jason Spake; 02.03.2018
comment
Добавление optionsValue в раскрывающийся список было проблемой выше. Я попробовал еще раз, закрыв все браузеры и свою визуальную студию. И это сработало сейчас. Должно быть, где-то кэшировалось значение. Спасибо. - person kaka1234; 02.03.2018