Knockout Select2 установить начальное значение по объекту - PullRequest
0 голосов
/ 18 сентября 2018

У меня есть веб-приложение Knockout.js, в котором есть выпадающий список select2.Я хочу связать id и текстовые значения с переменной, а не просто с идентификатором.Вот мои данные:

var cars = [{id: 1, name: 'Honda'}, {id: 2, name: 'Toyota'}, {id: 3, name: 'Dodge'}];
var selectedCar = ko.observable();

Вот мой HTML:

<select data-bind="value: selectedCar, optionsCaption: 'Select', optionsText: 'name', options: cars"></select>

Так что теперь, когда я выбираю что-то в раскрывающемся списке, моя переменная содержит весь объект, например, так:

selectedCar = {id: 1, name: 'Honda'};

Единственная проблема возникает, когда вы загружаете страницу и хотите, чтобы в раскрывающемся меню было задано определенное значение.Несмотря на то, что перед рендерингом html переменная selectedCar установлена ​​в {id: 1, name: 'Honda'}, когда для страницы отображается, в раскрывающемся списке ничего не задано, для него просто устанавливается заполнитель «Выбор».

Что я делаюнеправильно?

Ответы [ 2 ]

0 голосов
/ 18 сентября 2018

value поля выбора станет объектом, который соответствует выбранному элементу или свойству, установленному в параметре optionsValue.Таким образом, в случае объектов, выбранное вами значение должно быть тем же экземпляром, который существует в массиве.Наличие другого экземпляра объекта оказывается структурно эквивалентным недостаточно.

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

function ViewModel(data) {
    this.cars = data.cars;
    this.selectedCarId = ko.observable(data.selectedCarId);
    this.selectedCar = ko.computed(() => {
        let selectedCarId = this.selectedCarId();
        return this.cars.find(c => c.id === selectedCarId);
    });
}

let model = {
    cars: [
        { id: 1, name: 'Honda' },
        { id: 2, name: 'Toyota' },
        { id: 3, name: 'Dodge' }
    ],
    selectedCarId: 2
};
ko.applyBindings(new ViewModel(model), document.getElementById('content'));






  
  selectedCarId: 
  selectedCar: 
  
  

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

function ViewModel(data) {
    this.cars = data.cars;
    this.selectedCar = ko.observable(
        data.cars.find(c => c.id === data.selectedCarId)
    );
}
0 голосов
/ 18 сентября 2018

Если вы хотите привязать идентификатор и текстовое значение к переменной, вам необходимо использовать привязку optionsValue и привязать к ней весь контекст ($data);

<select data-bind="value: selectedCar, 
                   optionsCaption: 'Select', 
                   optionsText: 'name', 
                   options: cars, 
                   optionsValue: $data"></select>

Обычномы бы указали идентификатор или что-то еще, чтобы получить начальное значение выбрано.Так что, как и в вашем вопросе, имеет смысл предоставить весь объект {id: 1, name: 'Honda'} в качестве начального значения для selectedCar, если мокрое значение установлено optionsValue: $data, а не $optionsValue: 'id'.

( ВАЖНО ) Но оказывается, что это не работает, потому что мы создаем новый объект, и поэтому тест на равенство Knockout не пройдёт, когда он сравнит объекты cars собъект внутри selectedCar.Правильный способ установить начальное значение: cars[0].


Я уверен, что это опечатка, но я все равно уточню: когда вы создаете любую переменную, к которой должен обращатьсяHTML вам нужно привязать его к this, который будет ссылкой на viewModel.

this.cars = [{id: 1, name: 'Honda'}, {id: 2, name: 'Toyota'}, {id: 3, name: 'Dodge'}];
this.selectedCar = ko.observable();

Давайте проверим все это с помощью скрипки:

var viewModel = function(){
  var self = this;
  self.cars = [{id: 1, name: 'Honda'}, {id: 2, name: 'Toyota'}, {id: 3, name: 'Dodge'}];
  self.selectedCar = ko.observable(self.cars[0]);
  

};

ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<select data-bind="value: selectedCar, optionsCaption: 'Select', optionsText: 'name', optionsValue:$data, options: cars"></select>

<!-- to verify that we are getting the entire object -->
<p data-bind="text: ko.toJSON(selectedCar)"></p>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...