Нокаут привязывает текстовую метку к выпадающему значению выбранного варианта текста

Есть ли простой способ привязать текстовое поле div к изменению на основе текстового значения выбранного параметра в раскрывающемся списке на той же странице?

<div data-bind="text: dropdownValue"></div>
<select>
  <option value="1">Value1</option>
  <option value="2">Value2</option>
</select>

Обратите внимание: я не хочу помещать значения в элемент select с помощью javascript. Я хотел бы привязываться к значению прямо из HTML. Я также могу включить jQuery, чтобы он работал.

Ответ 1

Я искал аналогичную функциональность в чем-то, что вчера собрался и не смог найти, поэтому я просто изменил то, что я хранил в атрибутах value. Иногда это самое простое решение.

Вот быстрое и просто уродливое решение проблемы с помощью jQuery:

HTML

<div data-bind="text: dropdownText"></div>
<select data-bind="value: dropdownValue" id="dropdown">
  <option value="1">Value1</option>
  <option value="2">Value2</option>
</select>

JS

function ViewModel() {
    var self = this;
    this.dropdownValue = ko.observable();
    this.dropdownText = ko.computed(function() {
        return $("#dropdown option[value='" + self.dropdownValue() + "']").text();
    });
};

ko.applyBindings(new ViewModel());

Пример в реальном времени: http://jsfiddle.net/5PkBF/

Если вы хотите сделать это в нескольких местах, вероятно, лучше всего написать пользовательскую привязку, например:

HTML

<div data-bind="text: dropdownValue"></div>
<select data-bind="selectedText: dropdownValue">
  <option value="1">Value1</option>
  <option value="2">Value2</option>
</select>

JS

ko.bindingHandlers.selectedText = {
    init: function(element, valueAccessor) {
        var value = valueAccessor();
        value($("option:selected", element).text());

        $(element).change(function() {
            value($("option:selected", this).text());
        });
    },
    update: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        $("option", element).filter(function(i, el) { return $(el).text() === value; }).prop("selected", "selected");
    }
};

function ViewModel() {
    this.dropdownValue = ko.observable();
};

ko.applyBindings(new ViewModel());

Пример в реальном времени: http://jsfiddle.net/5PkBF/1/

Ответ 2

Вот как я реализовал подобную функцию. У меня была наблюдаемая, определенная в моей модели под названием "dropDownValue". У меня также был наблюдаемый массив, называемый "dropDownValues". Мой HTML выглядел примерно так:

<span data-bind="text: dropDownValue"></span>
<select data-bind="options: dropDownValues, optionsValue: 'FieldText', optionsText: 'FieldText', value: dropDownValue"></select>

Обратите внимание, что я использовал одно и то же поле для optionsValues ​​и optionsText (в этом случае действительно не нужны опцииText). В моем приложении "dropDownValue" было предварительно заполнено в другом месте, поэтому, когда я открыл диалоговое окно с указанным выше в нем, я хотел, чтобы он по умолчанию был ранее заполненным значением, а также привязывал его так, чтобы, если пользователь изменил его, я может отразить это изменение в базе данных.