- KnockoutJS 教程
- KnockoutJS - 首页
- KnockoutJS - 概述
- KnockoutJS - 环境设置
- KnockoutJS - 应用
- KnockoutJS - MVVM 框架
- KnockoutJS - 可观察对象
- 计算可观察对象
- KnockoutJS - 声明式绑定
- KnockoutJS - 依赖跟踪
- KnockoutJS - 模板
- KnockoutJS - 组件
- KnockoutJS 资源
- KnockoutJS - 快速指南
- KnockoutJS - 资源
- KnockoutJS - 讨论
KnockoutJS - 组件
组件是组织大型应用程序UI代码、构建结构和提高代码可重用性的一种重要方式。
它继承自或嵌套于其他组件。对于加载和配置,它定义了自己的约定或逻辑。
它被打包以便在整个应用程序或项目中重用。代表应用程序的完整部分或小型控件/部件。它可以按需加载或预加载。
组件注册
组件可以使用ko.components.register() API 注册。它有助于在 KO 中加载和表示组件。注册需要组件名称和配置。配置指定如何确定viewModel和模板。
语法
组件可以按如下方式注册:
ko.components.register('component-name', { viewModel: {...}, //function code template: {....) //function code });
组件名称可以是任何非空字符串。
viewModel是可选的,可以采用下一节列出的任何viewModel格式。
template是必需的,可以采用下一节列出的任何模板格式。
声明ViewModel
下表列出了可以用来注册组件的viewModel格式。
序号 | viewModel格式及说明 |
---|---|
1 | 构造函数 它为每个组件创建一个单独的viewModel对象。该对象或函数用于绑定到组件视图。 function SomeComponentViewModel(params) { this.someProperty = params.something; } ko.components.register('component name', { viewModel: SomeComponentViewModel, template: ... }); |
2 | 共享对象实例 viewModel对象实例是共享的。传递instance属性以直接使用该对象。 var sharedViewModelInstance = { ... }; ko.components.register('component name', { viewModel: { instance: sharedViewModelInstance }, template: ... }); |
3 | createViewModel 它调用一个充当工厂的函数,该函数可用作可以返回对象的视图模型。 ko.components.register('component name', { viewModel: { createViewModel: function (params, componentInfo) { ... //function code ... } }, template: .... }); |
4 | AMD模块 这是一种用于定义模块的模块格式,其中模块和依赖项都是异步加载的。 ko.components.register('component name', { viewModel: { require: 'some/module/name' }, template: ... }); define(['knockout'], function(ko) { function MyViewModel() { // ... } return MyViewModel; }); |
声明模板
下表列出了可以用来注册组件的模板格式。
序号 | 模板格式 |
---|---|
1 | 元素ID ko.components.register('component name', { template: { element: 'component-template' }, viewModel: ... }); |
2 | 元素实例 var elemInstance = document.getElementById('component-template'); ko.components.register('component name', { template: { element: elemInstance }, viewModel: ... }); |
3 | 标记字符串 ko.components.register('component name', { template: '<input data-bind = "value: yourName" />\ <button data-bind = "click: addEmp">Add Emp </button>', viewModel: ... }); |
4 | DOM节点 var emp = [ document.getElementById('node 1'), document.getElementById('node 2'), ]; ko.components.register('component name', { template: emp, viewModel: ... }); |
5 | 文档片段 ko.components.register('component name', { template: someDocumentFragmentInstance, viewModel: ... }); |
6 | AMD模块 ko.components.register('component name', { template: { require: 'some/template' }, viewModel: ... }); |
作为单个AMD模块注册的组件
AMD模块本身可以注册组件,无需使用viewModel/template对。
ko.components.register('component name',{ require: 'some/module'});
组件绑定
有两种组件绑定方式。
完整语法 - 它将参数和对象传递给组件。它可以使用以下属性传递。
name - 添加组件名称。
params - 它可以在组件上以对象形式传递多个参数。
<div data-bind='component: { name: "tutorials point", params: { mode: "detailed-list", items: productsList } }'> </div>
简写语法 - 它将字符串作为组件名称传递,并且不包含参数。
<div data-bind = 'component: "component name"'></div>
仅模板组件 - 组件只能定义模板,而不指定viewModel。
ko.components.register('component name', { template:'<input data-bind = "value: someName" />, });
无需容器元素即可使用组件 - 组件无需使用额外的容器元素即可使用。这可以通过使用无容器流控制来完成,这类似于注释标签。
<!--ko.component: ""--> <!--/ko-->
自定义元素
自定义元素是渲染组件的一种方式。在这里,您可以直接编写自描述的标记元素名称,而不是定义占位符,组件通过它进行绑定。
<products-list params = "name: userName, type: userType"></products-list>
传递参数
params属性用于将参数传递给组件viewModel。它类似于data-bind属性。params属性的内容被解释为JavaScript对象文字(就像data-bind属性一样),因此您可以传递任何类型的任意值。它可以按以下方式传递参数:
父组件和子组件之间的通信 - 组件本身不会被实例化,因此viewmodel属性是从组件外部引用的,因此将被子组件viewmodel接收。例如,您可以在下面的语法中看到ModelValue是父viewmodel,它被子viewmodel构造函数ModelProperty接收。
传递可观察表达式 - params参数中有三个值。
simpleExpression - 它是一个数值。它不涉及任何可观察对象。
simpleObservable - 它是定义在父viewModel上的实例。父viewModel将自动获取子viewModel对可观察对象所做的更改。
observableExpression - 表达式在表达式本身被求值时读取可观察对象。当可观察对象的值发生变化时,表达式的结果也会随着时间而变化。
我们可以按如下方式传递参数:
<some-component params = 'simpleExpression: 1 + 1, simpleObservable: myObservable, observableExpression: myObservable() + 1'> </some-component>
我们可以按如下方式在viewModel中传递参数:
<some-component params = 'objectValue:{a: 3, b: 2}, dateValue: new date(), stringValue: "Hi", numericValue:123, boolValue: true/false, ModelProperty: ModelValue'> </some-component>
将标记传递到组件中
接收到的标记用于创建组件,并被选择作为输出的一部分。以下节点作为组件模板中的输出的一部分传递。
template: { nodes: $componentTemplateNodes }
控制自定义元素标签名称
使用ko.components.register在组件中注册的名称,与自定义元素标签名称相同。我们可以通过覆盖它来控制使用getComponentNameForNode。
ko.components.getComponentNameForNode = function(node) { ... ... //function code ... }
注册自定义元素
如果使用默认组件加载器,则可以立即使用自定义元素,因此组件是使用ko.components.register注册的。如果我们没有使用ko.components.register并实现自定义组件加载器,则可以使用任何选择的元素名称来使用自定义元素。当您使用ko.components.register时,无需指定配置,因为自定义组件加载器不再使用它。
ko.components.register('custom-element', { ......... });
示例
<!DOCTYPE html> <head> <title>KnockoutJS Components</title> <script src = "https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> </head> <body> <!--params attribute is used to pass the parameter to component viewModel.--> <click params = "a: a, b: b"></click> <!--template is used for a component by specifying its ID --> <template id = "click-l"> <div data-bind = "text: a"></div> <!--Use data-bind attribute to bind click:function() to ViewModel. --> <button data-bind = "click:function(){callback(1)}">Increase</button> <button data-bind = "click:function(){callback(-1)}">Decrease</button> </template> <script> //Here components are registered ko.components.register('click', { viewModel: function(params) { self = this; this.a = params.a; this.b = params.b; this.callback = function(num) { self.b(parseInt(num)); self.a( self.a() + parseInt(num) ); }; }, template: { element: 'click-l' } }); //keeps an eye on variable for any modification in data function viewModel() { this.a = ko.observable(2); this.b = ko.observable(0); } ko.applyBindings(new viewModel() ); </script> </body> </html>
输出
让我们执行以下步骤来查看上述代码是如何工作的:
将上述代码保存在component_register.htm文件中。
在浏览器中打开此HTML文件。
组件加载器
组件加载器用于为给定的组件名称异步传递template/viewModel对。
默认组件加载器
默认组件加载器取决于显式注册的配置。每个组件在使用前都会被注册。
ko.components.defaultLoader
组件加载器实用函数
默认组件加载器可以使用以下函数进行读写。
序号 | 实用函数及说明 |
---|---|
1 | ko.components.register(name, configuration) 注册组件。 |
2 | ko.components.isRegistered(name) 如果特定组件名称已注册,则返回true,否则返回false。 |
3 | ko.components.unregister(name) 从注册表中删除组件名称。 |
4 | ko.components.get(name, callback) 此函数依次转到每个注册的加载器,以查找谁首先传递了组件名称的viewModel/template定义。然后,它通过调用callback来返回viewModel/template声明。如果注册的加载器找不到关于组件的任何信息,则它将调用callback(null)。 |
5 | ko.components.clearCachedDefinition(name) 当我们想要清除给定的组件缓存条目时,可以调用此函数。如果下次需要该组件,加载器将再次被咨询。 |
实现自定义组件加载器
自定义组件加载器可以按以下方式实现:
getConfig(name, callback) - 根据名称,我们可以以编程方式传递配置。我们可以调用callback(componentConfig)来传递配置,其中对象componentConfig可以被loadComponent或任何其他加载器使用。
loadComponent(name, componentConfig, callback) - 此函数根据配置方式解析config的viewModel和template部分。我们可以调用callback(result)来传递viewmodel/template对,其中对象result由以下属性定义。
template - 必需。返回DOM节点数组。
createViewModel(params, componentInfo) - 可选。根据viewModel属性的配置方式返回viewModel对象。
loadTemplate(name, templateConfig, callback) - 使用自定义逻辑在模板中传递DOM节点。对象templateConfig是来自对象componentConfig的模板的属性。callback(domNodeArray)被调用以传递DOM节点数组。
loadViewModel(name, templateConfig, callback) - 使用自定义逻辑在viewModel配置中传递viewModel工厂。