找到你要的答案

Q:Use knockout to show or hide element by selected drop-down displayed text and not its value?

Q:使用下拉显示或隐藏元素选定的下拉显示的文本,而不是它的价值?

I'm trying to get a drop-down list field to show or hide a certain div element based on the selected displayed text of the drop-down and not its value. I have a simple example below that shows it works when you set the data-bind to value:

<DIV data-bind="visible: chosenCountry() === 'GBR'">
<SELECT id="countryList" data-bind="value: chosenCountry">

But the drop-down field becomes an empty list when you set it to text:

<DIV data-bind="visible: chosenCountry() === 'United Kingdom'">
<SELECT id="countryList" data-bind="text: chosenCountry">

Below is my complete example:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
  <HEAD>
    <TITLE></TITLE>
  </HEAD>
  <BODY>
    <DIV data-bind="visible: chosenCountry() === 'GBR'">
      You will see this message only when the chosen country is the United Kingdom.
    </DIV><SELECT id="countryList" data-bind="value: chosenCountry">
      <OPTION value="AUS">
        Australia
      </OPTION>
      <OPTION value="BHS">
        Bahamas
      </OPTION>
      <OPTION value="GBR">
        United Kingdom
      </OPTION>
    </SELECT> 
    <SCRIPT src="knockout-3.3.0.js" type="text/javascript">
    </SCRIPT>
    <SCRIPT type="text/javascript">        
        var viewModel = {
                chosenCountry: ko.observable("GBR")
        };

                        ko.applyBindings(viewModel);
    </SCRIPT>
  </BODY>
</HTML>

我想得到一个下拉列表字段显示或隐藏一个基于选定的文本显示的下拉而不是其价值一定的div元素。下面我有一个简单的例子,说明当你将数据绑定到值时它会运行:

<DIV data-bind="visible: chosenCountry() === 'GBR'">
<SELECT id="countryList" data-bind="value: chosenCountry">

但是,当您将下拉字段设置为文本时,该字段将成为空列表:

<DIV data-bind="visible: chosenCountry() === 'United Kingdom'">
<SELECT id="countryList" data-bind="text: chosenCountry">

下面是我的完整例子:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<HTML>
  <HEAD>
    <TITLE></TITLE>
  </HEAD>
  <BODY>
    <DIV data-bind="visible: chosenCountry() === 'GBR'">
      You will see this message only when the chosen country is the United Kingdom.
    </DIV><SELECT id="countryList" data-bind="value: chosenCountry">
      <OPTION value="AUS">
        Australia
      </OPTION>
      <OPTION value="BHS">
        Bahamas
      </OPTION>
      <OPTION value="GBR">
        United Kingdom
      </OPTION>
    </SELECT> 
    <SCRIPT src="knockout-3.3.0.js" type="text/javascript">
    </SCRIPT>
    <SCRIPT type="text/javascript">        
        var viewModel = {
                chosenCountry: ko.observable("GBR")
        };

                        ko.applyBindings(viewModel);
    </SCRIPT>
  </BODY>
</HTML>
answer1: 回答1:

A custom binding that tracks when the value of the select changes and pulls its text component will work for you:

ko.bindingHandlers.selectedTextA = {
    init: function (element, valueAccessor, allBindings) {
        var valueBinding = allBindings().value;
        valueBinding.subscribe(function () {
            var idx = element.selectedIndex,
                dest = valueAccessor();
            dest(idx >= 0 ? element.options[idx].text : undefined);
        });
        valueBinding.notifySubscribers();
    }
};

This ensures that the text variable is tightly coupled to the value variable, which setting a change event handler doesn't do. My fiddle programmatically changes the value variable. Using selectedTextA as the binding handler causes the expected update, while selectedTextB does not.

http://jsfiddle.net/f1bdr00s/

一个自定义绑定,跟踪时的值的选择更改和拉动其文本组件将为您工作:

ko.bindingHandlers.selectedTextA = {
    init: function (element, valueAccessor, allBindings) {
        var valueBinding = allBindings().value;
        valueBinding.subscribe(function () {
            var idx = element.selectedIndex,
                dest = valueAccessor();
            dest(idx >= 0 ? element.options[idx].text : undefined);
        });
        valueBinding.notifySubscribers();
    }
};

这确保文本变量与值变量紧密耦合,该变量变量设置事件处理程序不做。我的小提琴以编程方式改变变量的值。使用selectedtexta为结合处理导致预期的更新,而selectedtextb不。

http://jsfiddle.net/f1bdr00s/

answer2: 回答2:

The value binding will only work with the value. If you want to bind to the text, you'll need a custom binding. Something like this:

ko.bindingHandles.selectedText = {
    init: function (element, valueAccessor) {
        ko.utils.registerEventHandler(element, "change", function () {
            var modelValue = valueAccessor(),
                selectedIndex = element.selectedIndex;
            modelValue(selectedIndex >= 0 ? element.options[selectedIndex].text : undefined);
        });
    }
};

值绑定只与值一起工作。如果要绑定到文本,则需要自定义绑定。像这样的东西:

ko.bindingHandles.selectedText = {
    init: function (element, valueAccessor) {
        ko.utils.registerEventHandler(element, "change", function () {
            var modelValue = valueAccessor(),
                selectedIndex = element.selectedIndex;
            modelValue(selectedIndex >= 0 ? element.options[selectedIndex].text : undefined);
        });
    }
};
answer3: 回答3:

The text binding does not apply to selects. There is no binding to track the label instead of the value. If you didn't want to write a custom binding for that, you would need to write a function to lookup the name from the code. This assumes you make the options part of your code, rather than your HTML.

<DIV data-bind="visible: chosenCountryName() === 'United Kingdom'">You will see this message only when the chosen country is the United Kingdom.</DIV>
<SELECT id="countryList" data-bind="options:countryOptions, optionsText: 'text', optionsValue: 'value', value: chosenCountry"></SELECT>

The code could be:

var viewModel = {
    countryOptions: [
        {text: 'Australia', value: 'AUS'},
        {text: 'Bahamas', value: 'BHS'},
        {text: 'United Kingdom', value: 'GBR'}

        ],
    chosenCountry: ko.observable("GBR")
};

viewModel.chosenCountryName = ko.computed(function () {
    var code = viewModel.chosenCountry();
    for (var i = 0; i < viewModel.countryOptions.length; ++i) {
        var item = viewModel.countryOptions[i];
        if (item.value === code) return item.text;
    }
});

ko.applyBindings(viewModel);

文本绑定不适用于选择。没有绑定来跟踪标签而不是值。如果您不想为此编写自定义绑定,则需要编写一个函数来从代码中查找名称。这是假设你让你的代码的选项的一部分,而不是你的HTML。

<DIV data-bind="visible: chosenCountryName() === 'United Kingdom'">You will see this message only when the chosen country is the United Kingdom.</DIV>
<SELECT id="countryList" data-bind="options:countryOptions, optionsText: 'text', optionsValue: 'value', value: chosenCountry"></SELECT>

代码可以:

var viewModel = {
    countryOptions: [
        {text: 'Australia', value: 'AUS'},
        {text: 'Bahamas', value: 'BHS'},
        {text: 'United Kingdom', value: 'GBR'}

        ],
    chosenCountry: ko.observable("GBR")
};

viewModel.chosenCountryName = ko.computed(function () {
    var code = viewModel.chosenCountry();
    for (var i = 0; i < viewModel.countryOptions.length; ++i) {
        var item = viewModel.countryOptions[i];
        if (item.value === code) return item.text;
    }
});

ko.applyBindings(viewModel);
knockout.js  html-select  show-hide