KnockoutJS 3.X API 第四章 表单绑定(11) options绑定
目的
options绑定主要用于下拉列表中(即<select>元素)或多选列表(例如,<select size='6'>)。此绑定不能与除<select>元素之外的任何其他元素一起使用。
其值应该是一个数组(或监控属性数组)。
注意:对于多选列表,设置该选项被选中,或读取其中被选中的选项,需要使用的selectedOptions绑定。对于单选择列表,可以结合value绑定读取和写入选定的选项的。。
示例1:下拉列表
Destination country:
源码:
<p> Destination country: <select data-bind="options: availableCountries"></select> </p> <script type="text/javascript"> var viewModel = { // These are the initial options availableCountries: ko.observableArray(['France', 'Germany', 'Spain']) }; // ... then later ... viewModel.availableCountries.push('China'); // Adds another option </script>
示例2:多选列表
Choose some countries you would like to visit:
源码:
<p> Choose some countries you would like to visit: <select data-bind="options: availableCountries" size="5" multiple="true"></select> </p> <script type="text/javascript"> var viewModel = { availableCountries: ko.observableArray(['France', 'Germany', 'Spain']) }; </script>
示例3:任意JS对象的下拉列表
Your country:
源码:
<p> Your country: <select data-bind="options: availableCountries, optionsText: 'countryName', value: selectedCountry, optionsCaption: 'Choose...'"></select> </p> <div data-bind="visible: selectedCountry"> <!-- Appears when you select something --> You have chosen a country with population <span data-bind="text: selectedCountry() ? selectedCountry().countryPopulation : 'unknown'"></span>. </div> <script type="text/javascript"> // Constructor for an object with two properties var Country = function(name, population) { this.countryName = name; this.countryPopulation = population; }; var viewModel = { availableCountries : ko.observableArray([ new Country("UK", 65000000), new Country("USA", 320000000), new Country("Sweden", 29000000) ]), selectedCountry : ko.observable() // Nothing selected by default }; </script>
示例4:任意JS对象的下拉列表并以计算的方式显示文本
源码:
<!-- Same as example 3, except the <select> box expressed as follows: --> <select data-bind="options: availableCountries, optionsText: function(item) { return item.countryName + ' (pop: ' + item.countryPopulation + ')' }, value: selectedCountry, optionsCaption: 'Choose...'"> </select>
备注,示例4与示例3的唯一区别在于optionsText的显示方式。
参数
-
optionsCaption
有时候,你可能不希望默认选择选中任何特定选项。但单选择下拉列表中通常选择一些默认项目启动,因此,如何避免预选的东西,通常的解决方法是用一个特殊的虚拟选项,只是写着“选择项”或“请选择一个选项”或类似的东西,并具有在默认情况下选择了一个前缀的选项列表。
这很容易做到:只需添加额外的参数有名字
optionsCaption
,它的值是显示一个字符串。例如:<select data-bind='options: myOptions, optionsCaption: "Select an item...", value: myChosenValue'></select>
KO会前缀一个显示文本的项目列表“选择项目...”它的值是
undefined
。因此,如果myChosenValue
保持值undefined
,则虚设选项将被选中。如果optionsCaption
参数是监控属性,则初始项目的文本将根据监控属性值的变化而变化。 -
optionsText
见上面的示例3,在这种情况下,你需要选择该对象的属性应显示为下拉列表或多选列表的文本。示例3显示了如何可以通过传递一个额外的参数指定属性名
optionsText
。如果你不希望下拉列表中的每个项目显示的只是一个简单的属性值的文本,你可以给
optionsText
选项传递一个JavaScript函数,并提供您自己任意的逻辑在表示对象的条件计算显示的文本。如示例4。 -
optionsValue
类似
optionsText
,您还可以传递一个名为optionsValue的附加参数,以指定应使用哪些对象属性来设置KO生成的<option>元素上的value属性。 您还可以指定JavaScript函数来确定此值。 此函数将接收所选项作为其唯一参数,并应返回用于<option>元素的value属性的字符串。通常,您只想使用optionsValue作为一种确保KO在更新可用选项集时正确保留选择的方法。 例如,如果您通过Ajax调用重复获取“car”对象的列表,并且想要确保所选择的汽车被保留,您可能需要将optionsValue设置为“carId”或每个“car”对象具有的唯一标识符 ,否则KO不一定知道先前的“汽车”对象中的哪一个对应于新集合中的项目。
-
optionsIncludeDestroyed
有时你可能想将一个数组条目标记为已删除,但实际上没有真的删除。 这被称为非破坏性删除。
默认情况下,选项绑定将跳过(即隐藏)标记为已销毁的任何数组条目。 如果要显示已销毁的条目,请指定此附加参数,例如:
<select data-bind='options: myOptions, optionsIncludeDestroyed: true'></select>
-
optionsAfterRender
如果需要在生成的选项元素上运行一些自定义逻辑,可以使用optionsAfterRender回调。 见下文注2。
-
selectedOptions
对于多选列表,可以使用selectedOptions读取和写入所选状态。 技术上这是一个单独的绑定,你可以参考下一节的selectedOptions绑定。
-
valueAllowUnset
如果你想让Knockout允许你的模型属性获取在你的<select>元素没有相应条目的值(并通过使<select>元素为空,显示这个值),然后参见第四章 value绑定的valueAllowUnset。
备注1:设置/更改选项时保留选择
当选项绑定更改您的<select>元素中的选项集时,KO将尽可能不改变用户的选择。 因此,对于单选择下拉列表,仍将选择先前选择的选项值,而对于多选列表,仍将选择所有先前选择的选项值(除非您已删除 一个或多个选项)。
这是因为选项绑定试图独立于值绑定(控制单选列表的选择)和selectedOptions绑定(控制多选列表的选择)。
备注2:对生成的选项进行处理
如果需要在生成的选项元素上运行一些自定义逻辑,可以使用optionsAfterRender回调。 每当将一个选项元素插入到列表中时,将调用回调函数,并使用以下参数:
- 插入的
option
元素 - 与其绑定的数据项,或对于caption元素未定义的数据项
下面是一个使用optionsAfterRender向每个选项添加禁用绑定的示例:
源码:
<select size=3 data-bind=" options: myItems, optionsText: 'name', optionsValue: 'id', optionsAfterRender: setOptionDisable"> </select> <script type="text/javascript"> var vm = { myItems: [ { name: 'Item 1', id: 1, disable: ko.observable(false)}, { name: 'Item 3', id: 3, disable: ko.observable(true)}, { name: 'Item 4', id: 4, disable: ko.observable(false)} ], setOptionDisable: function(option, item) { ko.applyBindingsToNode(option, {disable: item.disable}, item); } }; ko.applyBindings(vm); </script>