绑定
什么是约束力
基本上,绑定或数据绑定是将 ViewModel 链接到 Views(模板)的一种方式,反之亦然。KnockoutJS 使用双向数据绑定,这意味着对 ViewModel 的更改会影响 View,而对 View 的更改可能会影响 ViewModel。
引擎盖下(简短概述)
绑定只是允许你解决特定任务的插件(脚本)。根据你的 ViewModel,此任务通常是更改标记(html)。
例如,text
绑定允许你在 ViewModel 更改时显示文本并动态更改它。
KnockoutJS 带有许多强大的绑定,并允许你使用自己的自定义绑定进行扩展。
最重要的是绑定并不神奇,它们根据一组规则工作,任何时候你不确定绑定的作用,它需要什么参数或何时更新视图你可以参考绑定的源代码。
请考虑以下自定义绑定示例:
ko.bindingHandlers.debug = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
ko.computed(function () {
var value = ko.unwrap(valueAccessor());
console.log({
value: value,
viewModel: viewModel,
bindingContext: bindingContext
});
}, null, { disposeWhenNodeIsRemoved: element });
}
};
- 绑定有一个名称 -
debug
所以你可以使用如下:
data-bind="debug: 'foo'"
- 启动绑定时,会调用
init
方法一次。其余的更新由匿名计算处理,该计算在删除element
时处理。 - 绑定打印到控制台的几件事:在我们的例子中传递的值这个值是
foo
(这个值也可以是可观察的,因为ko.unwrap
方法用于读取它),当前的 viewModel 和 bindingContext。 - 每当传递的值更改时,绑定都会将更新的信息打印到控制台。
- 此绑定不能与虚拟元素(在 html 注释中)一起使用,仅适用于真实元素,因为
ko.virtualElements.allowedBindings.debug
标志未设置为 true。
何时使用括号
没有任何额外的插件 ,KnockoutJS 将只能查看 ViewModel 上可观察的属性的实时 View 更新 (常规 observable
,还有 computed
,pureComputed
,observableArray
等)。可以像这样创建一个 observable:
var vm = { name: ko.observable("John") };
在这种情况下,vm.name
是一个具有两个独立模式 的函数 :
- Getter:
vm.name()
,没有参数,将获得当前值; - Setter:
vm.name("Johnnyboy")
,带参数,将设置一个新值。
在内置数据绑定中,你始终可以使用 getter 表单,有时你实际上可以省略括号,绑定将为你有效地添加它们。所以这些是等价的:
<p data-bind="text: name"></p> ... will work
<p data-bind="text: name()"></p> ... works too
但这会失败:
<p data-bind="text: 'Hello, ' + name + '!'"></p> ... FAILS!
因为只要在将值传递给数据绑定(包括值比较)之前想要执行某些操作,就需要正确获取所有可观察对象的值,例如:
<p data-bind="text: 'Hello, ' + name() + '!'"></p> ... works
有关更多详细信息,请参阅此问答 。