绑定

什么是约束力

基本上,绑定或数据绑定是将 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 });
    }
};
  1. 绑定有一个名称 - debug 所以你可以使用如下:

data-bind="debug: 'foo'"

  1. 启动绑定时,会调用 init 方法一次。其余的更新由匿名计算处理,该计算在删除 element 时处理。
  2. 绑定打印到控制台的几件事:在我们的例子中传递的值这个值是 foo(这个值也可以是可观察的,因为 ko.unwrap 方法用于读取它),当前的 viewModel 和 bindingContext。
  3. 每当传递的值更改时,绑定都会将更新的信息打印到控制台。
  4. 此绑定不能与虚拟元素(在 html 注释中)一起使用,仅适用于真实元素,因为 ko.virtualElements.allowedBindings.debug 标志未设置为 true。

何时使用括号

没有任何额外的插件 ,KnockoutJS 将只能查看 ViewModel 上可观察的属性的实时 View 更新 (常规 observable,还有 computedpureComputedobservableArray 等)。可以像这样创建一个 observable:

var vm = { name: ko.observable("John") };

在这种情况下,vm.name 是一个具有两个独立模式函数

  1. Getter:vm.name(),没有参数,将获得当前值;
  2. 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

有关更多详细信息,请参阅此问答