KnockoutJS - component 绑定
此绑定用于将组件插入 DOM 元素并选择性地传递参数。此绑定可以通过以下两种方式实现 −
- 简写语法
- 完整语法
简写语法
在此方法中,仅指定组件名称,而不指定任何参数。
语法
<div data-bind = 'component: "component-name"'></div>
传递的参数值可以是可观察的。因此,每当可观察对象发生变化时,旧的组件实例将被释放,并根据刷新的参数值创建新的组件实例。
完整语法
此方法以对象的形式接受参数。
语法
<div data-bind = 'component: { name: "component-name", params: { param1: value1, param2:value2 ...} }'></div>
该对象由以下两项组成 −
name − 这是要插入的组件的名称。如前所述,这可以是可观察对象。
params - 这是要传递给组件的对象。大多数情况下,这将是一个包含多个参数的键值对象。这大多数时候都是由 ViewModel 的构造函数接收的。
组件处理工作流程
下图解释了通过组件绑定注入组件时发生的过程。
![component lifecycle](/knockoutjs/images/component-lifecycle.jpg)
让我们详细看看这个过程 −
从组件加载器接收 ViewModel 工厂和模板 − 默认加载器请求并接收已注册的 ViewModel 和模板。默认情况下,这是一个异步过程。
克隆组件模板 − 在此步骤中,将克隆组件模板并将其插入 DOM 元素。现有内容(如果有)将被删除。
实例化 ViewModel(如果有) −在此步骤中,ViewModel 被实例化。如果 ViewModel 以构造函数的形式提供,则 KO 会调用。
new ViewModelName(params)
如果 ViewModel 以工厂函数的形式提供,即 createViewModel,则 KO 会调用。
createViewModel(params, yourcomponentInfo)
此处 yourcomponentInfo.element 是插入模板的元素。
将 ViewModel 绑定到视图 − 在此阶段,ViewModel 绑定到视图。如果未提供 ViewModel,则使用组件绑定中提到的参数进行绑定。
现在组件已准备就绪 − 在此阶段,组件已准备就绪并处于运行状态。组件会密切关注可观察的参数(如果有),以便写入更改的值。
如果组件丢失,则处置 ViewModel − 如果组件绑定名称值发生可观察的变化,或者某些控制流绑定删除了 DOM 元素容器本身(用于保存组件输出),则调用 ViewModel 的处置函数。处置发生在任何元素容器从 DOM 中删除之前。
示例
让我们看看下面的示例,它演示了组件绑定的使用。
<!DOCTYPE html> <head> <title>KnockoutJS Component binding</title> <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js" type = "text/javascript"></script> </head> <body> <h4>Component binding without parameters</h4> <div data-bind = 'component: "calculate-sum"'></div> <h4>Component binding passing parameters</h4> <div data-bind = 'component: { name: "calculate-sum", params: { number1: 2, number2: 3 } }'></div> <script> ko.components.register('calculate-sum', { viewModel: function(params) { this.number1 = ko.observable(params && params.number1); this.number2 = ko.observable(params && params.number2); this.result = ko.computed(function() { var sum = Number(this.number1()) + Number(this.number2()); if ( isNaN(sum) ) sum = 0; return sum; },this); }, template: 'Enter Number One: <input data-bind = "value: number1" /> <br> <br>'+ ' Enter Number Two: <input data-bind = "value: number2" /> <br> <br>'+ ' Sum = <span data-bind = "text: result" />' }); ko.applyBindings(); </script> </body> </html>
输出
让我们执行以下步骤来查看上述代码的工作原理 −
将上述代码保存在 component-bind.htm 文件中。
在浏览器中打开此 HTML 文件。
在两个文本框中输入数字,并观察总和是否计算出来。
观察
仅模板组件
无需 ViewModel 即可创建组件。该组件可以仅包含如下所示的模板。
ko.components.register('my-component', { template: '<div data-bind = "text: productName"></div>' });
DOM 将如下所示 −
<div data-bind = 'component: { name: "my-component", params: { productName: someProduct.name } }'></div>
使用没有 DOM 容器元素的组件绑定
可能存在无法将组件插入 DOM 元素的情况。基本绑定仍可借助无容器语法执行,具体操作请参见以下注释标记。
<!--ko--> 和 <!--/ko--> 用作开始和结束标记,使其成为虚拟语法,并将数据绑定为真实容器。
内存管理和处置
处置函数可作为 ViewModel 的一部分进行选择添加。如果包含此函数,则每当组件丢失或容器元素本身被移除时,都会调用此函数。使用处置函数释放不需要的对象占用的资源是一种很好的做法,默认情况下这些资源不可进行垃圾回收。以下是几个示例 −
setInterval 方法将持续运行,直到明确清除。clearInterval (handle) 用于停止此过程。
ko.computed 属性需要明确处置。否则,它们可能仍会继续从其底层可观察对象接收通知。使用纯计算函数可以避免手动处置。
确保在订阅上使用 dispose() 方法,否则它会持续触发更改,直到处置为止。
在 DOM 元素上创建并在 createViewModel 内创建的自定义事件处理程序需要处置。
knockoutjs_declarative_bindings.html