目的
value绑定主要用于DOM元素给视图模型赋值用的。通常用于<input><select><textarea>等元素。
value绑定与text绑定的区别在于,value绑定中当用户编辑表单控件相关值的时候,值会自动更新视图模型的相关属性值,当视图模型的相关属性值被更新后,表单中相关的value绑定也会随之变化。
value绑定就像DOM和ViewModel的一个双向通道。而text绑定只是ViewModel到DOM的单向通道。
例如:
<p>Login name: <input data-bind="value: userName" /></p>
<p>Password: <input type="password" data-bind="value: userPassword" /></p> <script type="text/javascript">
var viewModel = {
userName: ko.observable(""), // Initially blank
userPassword: ko.observable("abc"), // Prepopulate
};
</script>
一些细节
主要技术细节:
- KO将会使用初始值设置value绑定的元素。当有新的值的时候,初始值将被覆盖
- 如果value绑定的是监控属性,那么之后的属性值更新就会被体现在DOM的value绑定上,如果不是监控属性,则只有第一次运行会更新DOM上的value绑定的值,之后就不会再变了。
- 如果你的value绑定不是数值型或字符型数据(例如一个对象或数组),那显示的文本内容将等同于yourParameter.toString()。最好还是绑定值型或字符型数据。
- 当用户编辑表单控件修改基于value绑定的元素值并移出焦点后,KO就会自动更新对应的视图模型的属性值,你也可以通过使用valueUpdate事件来控制。
其他技术细节:
- valueUpdate,KO定义了一系列的change事件,最常用包括如下事件:
-
"input"
-<input>
或<textarea>
元素的变化更新您的视图模型时的值。 -
"keyup"
- 当用户释放某个键更新您的视图模型 -
"keypress"
-当用户输入一个值更新您的视图模型。不像keyup
,这个会反复更新 -
"afterkeydown"
-当用户开始输入一个字符尽快更新您的视图模型。这通过捕获浏览器的keydown
事件,并异步处理该事件。这个事件在一些移动客户端可能不会起什么作用。
-
- valueAllowUnset,适用于<select>的value绑定,其他元素不起作用,具体请参考之后的备注2.
备注1:实时更新
如果你想要实时更新<input>或者<textarea>到你的视图模型,可以使用textInput绑定。具体的textInput细节将在之后的章节提到。
备注2:下拉列表<select>的绑定
KO在下拉列表绑定中,需要使用value绑定和options绑定(options绑定将在以后的章节中提到)。
使用valueAllowUnset与<select>元素
Select a country:
源码:
<p>
Select a country:
<select data-bind="options: countries,
optionsCaption: 'Choose one...',
value: selectedCountry,
valueAllowUnset: true"></select>
</p> <script type="text/javascript">
var viewModel = {
countries: ['Japan', 'Bolivia', 'New Zealand'],
selectedCountry: ko.observable('Latvia')
};
</script>
有很多时候,我们希望下拉列表中包含一个空白的或者没有包含在数据集合中的元素,比如choose one…,那么就可以使用valueAllowUnset:true来带到目的。如上述例子一样。
selectedCountry将保留Latvia,并将下拉列表中空白匹配给它。
备注3:绑定监控属性和非监控属性
如果你使用value
绑定的是一个监控属性,KO是能够建立一个双向绑定。
但是如果value绑定是一个非监控属性,则KO会进行以下处理:
如果引用一个简单的属性,也就是说,它只是在你的视图模型一个普通的属性,表单元素编辑时KO将设置表单元素的初始状态属性值。
例如:
First value:
First value:
Second value:
Second value:
Third value:
源码:
<p>First value: <input data-bind="value: firstValue"></p>
<p>First value:<span data-bind="text:firstValue"></span></p>
<!-- One-way binding. Populates textbox; syncs only from textbox to model. -->
<p>Second value: <input data-bind="value: secondValue"></p>
<p>Second value: <span data-bind="text: secondValue"></span></p>
<!-- No binding. Populates textbox, but doesn't react to any changes. -->
<p>Third value: <input data-bind="value: secondValue.length > 8"></p>
<script type="text/javascript">
var viewModel = {
firstValue: ko.observable("hello"), // Observable
secondValue: "hello, again" // Not observable
};
ko.applybindings(viewModel,document.getElementById("eq2"));
</script>