前言
options绑定控制什么样的options在drop-down列表里(例如:<select>)或者 multi-select 列表里 (例如:<select size='6'>)显示。此绑定不能用于<select>之外的元素。关联的数据应是数组(或者是observable数组),<select>会遍历显示数组里的所有的项。
对于multi-select列表,设置或者获取选择的多项需要使用selectedOptions绑定。对于single-select列表,你也可以使用value绑定读取或者设置元素的selected项。
Drop-down list
<p>Destination country: <select data-bind="options: availableCountries"></select></p> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var viewModel = { availableCountries: ko.observableArray(['France', 'Germany', 'Spain']) }; ko.applyBindings(viewModel); viewModel.availableCountries.push('China'); </script>
该参数是一个数组(或者observable数组)。对每个item,KO都会将它作为一个<option> 添加到<select>里,之前的options都将被删除。
如果参数是一个string数组,那你不需要再声明任何其它参数。<select>元素会将每个string显示为一个option。不过,如果你让用户选择的是一个JavaScript对象数组(不仅仅是string),那就需要设置optionsText和optionsValue这两个参数了。
如果参数是监控属性observable的,那元素的options项将根据参数值的变化而更新,如果不是,那元素的value值将只设置一次并且以后不在更新。
如果对上面的select UI元素加上multiple="true"
<select data-bind="options: availableCountries" multiple="true"></select>
这可以说是Multi-select list
Drop-down list展示的任意JavaScript对象,不仅仅是字符串
<p>Destination country: <select data-bind="options: availableCountries" multiple="true"></select></p> <p> Your country: <select data-bind="options: Countries,optionsText: 'countryName', value: selectedCountry, optionsCaption: 'Choose...'"> </select> </p> <div data-bind="visible: selectedCountry"> You have chosen a country with population <span data-bind="text: selectedCountry() ? selectedCountry().countryPopulation : 'unknown'"></span>. </div> <script type="text/javascript" src="~/Scripts/knockout-2.3.0.debug.js"></script> <script type="text/javascript"> var Country = function (name, population) { this.countryName = name; this.countryPopulation = population; }; var viewModel = { availableCountries: ko.observableArray(['France', 'Germany', 'Spain']), selectedCountry: ko.observable(), Countries: ko.observableArray([ new Country("UK", 65000000), new Country("USA", 320000000), new Country("Sweden", 29000000) ]) }; ko.applyBindings(viewModel); viewModel.availableCountries.push('China'); </script>
optionsCaption
有时候,默认情况下不想选择任何option项。但是single-select drop-down列表由于每次都要默认选择以项目,怎么避免这个问题呢?常用的方案是加一个“请选择的”或者“Select an item”的提示语,或者其它类似的,然后让这个项作为默认选项。
我们使用optionsCaption参数就能很容易实现,它的值是字符串型,作为默认项显示。例如:
<select data-bind='options: myOptions, optionsCaption: "Select an item...", value: myChosenValue'></select>
KO会在所有选项上加上这一个项,并且设置value值为undefined。所以,如果myChosenValue被设置为undefined(默认是observable的),那么上述的第一个项就会被选中
Drop-down list展示的任意JavaScript对象,显示text是function的返回值
<select data-bind="options: Countries, optionsText: function(item) { return item.countryName + ' (pop: ' + item.countryPopulation + ')' }, value: selectedCountry, optionsCaption: 'Choose...'"> </select>
optionsText
上面《Drop-down list展示的任意JavaScript对象,不仅仅是字符串》中展示的绑定JavaScript对象到option上 – 不仅仅是字符串。这时候你需要设置这个对象的那个属性作为drop-down列表或multi-select列表的text来显示。设置额外的参数optionsText将对象的属性名countryName作为显示的文本。
如果不想仅仅显示对象的属性值作为每个item项的text值,那你可以设置optionsText 为JavaScript 函数,然后再函数里通过自己的逻辑返回相应的值(该函数参数为item项本身)。
optionsValue
和optionsText类似, 你也可以通过额外参数optionsValue来声明对象的那个属性值作为该<option>的value值。
经典场景:如在更新options的时候想保留原来的已经选择的项。例如,当你重复多次调用Ajax获取car列表的时候,你要确保已经选择的某个car一直都是被选择上,那你就需要设置optionsValue为“carId”或者其它的unique标示符,否则的话KO找不知道之前选择的car是新options里的哪一项
selectedOptions
对于multi-select列表,你可以用selectedOptions读取和设置多个选择项。技术上看它是一个单独的绑定,有自己的文档,请参考: selectedOptions绑定。