нокаутный многовыборный selectedOptions содержит значения вместо объектов

#javascript #knockout.js

#javascript #knockout.js

Вопрос:

У меня есть выбор с атрибутом multiple. Для каждого параметра в выборе я хочу, чтобы был установлен атрибут title (который показывает всплывающую подсказку). Я также хочу получить выбранные параметры в виде массива объектов. Мне удалось получить то, что я хочу, за исключением того факта, что выбранные параметры возвращают не массив объектов, а массив значений. Я не могу понять, как я получаю объекты в этом массиве.

Это код, который я получил до сих пор:

HTML:

 <select multiple style="width: 150px;" size=15 
        data-bind="foreach: options, selectedOptions: selectedOptions">
    <option data-bind="text: Name, attr: { 'title': Name}"></option>
</select><br />
<button data-bind="click: showSelectedOptions">Show selection</button>
  

Javascript:

 function Option(id, name){
    var self = this;

    self.Id = id;
    self.Name = name;
}

function ViewModel(){
    var self = this;

    self.options = ko.observableArray([
        new Option(0, "NormalText"),
        new Option(1, "AnotherText"),
        new Option(2, "WaaaaaaaaaaaaaaaayTooLongText")
    ]);
    self.selectedOptions = ko.observableArray([]);

    self.showSelectedOptions = function(){
        alert(self.selectedOptions());
        //what I would like to have:
        //if (self.selectedOptions().length > 0)
        //    alert(self.selectedOptions()[0].Name);
    }
}

ko.applyBindings(new ViewModel());
  

И ссылка на скрипку для демонстрации: http://jsfiddle.net/c63Bb/1 /

Что мне нужно добавить или изменить, чтобы массив selectedOptions содержал объекты вместо строк?

Комментарии:

1. для этого вам не нужно использовать foreach . Посмотрите здесь

Ответ №1:

Попробуйте свой html следующим образом

 <select 
    data-bind="
        options: options,
        selectedOptions : selectedOptions,
        optionsText: 'Name',
        optionsCaption: 'Choose...'
    "
 size="5" multiple="true"></select>
  

ДЕМОНСТРАЦИЯ

Смотрите консоль для вывода

ПРАВКИ :

Чтобы добавить атрибуты к опции, которую вам нужно использовать optionsAfterRender .
Это доступно только в версии 3.1.0. Я заметил, что ваша скрипка использует 3.0.0.

 <select 
    data-bind="
        options: options,
        selectedOptions : selectedOptions,
        optionsText: 'Name',
        optionsAfterRender: $root.setTitle
    "
 size="5" multiple="true"></select><br />
<button data-bind="click: showSelectedOptions">Show selection</button>
  

И создайте fnction

 self.setTitle = function(option, item) {
    option.title = item.Name
}  
  

ДЕМОНСТРАЦИЯ

Ссылка

См. Примечание 2

Комментарии:

1. Но если я не использую foreach и использую привязку options, как я могу добавить атрибут title к тегу option внутри тега select и привязать к нему значение?

2. @Cornelis я обновил ответ, который вы можете увидеть сейчас.

3. Спасибо, optionsAfterRender выполняет свою работу. Хотя $root не требуется. На самом деле, это привело к ошибкам в моем исходном проекте, где мне нужно показать всплывающую подсказку. Я также пытался использовать $parent или $parents, но пока setTitle и options находятся в одной и той же ViewModel, вам не нужно переходить на другую ViewModel, используя $root или $parent или тому подобное.

4. Ну, это был только пример. Вы можете использовать любую модель для определения и ссылки на функцию в соответствии с вашими требованиями. Рад, что это помогло!!!

Ответ №2:

Подобно @MuhammadRaheel, я использовал optionsAfterRender :

 <select data-bind="optionsAfterRender: myFunc, ...">
  

Но мне нужно было использовать ko.applyBindingsToNode :

 var self.myFunc = function(option, item) {
    ko.applyBindingsToNode(option, { attr: { title: 'Tooltip!' } }, item);
}
  

Ответ №3:

Используйте привязки options и optionsText вместо foreach:

 <select multiple style="width: 150px;" size=15 
    data-bind="options: options, optionsText: 'Name', selectedOptions: selectedOptions">
<option data-bind="text: Name, attr: { 'title': Name}"></option>
</select>
  

Вот демонстрация: http://jsfiddle.net/p5E8y /