概述 :组件和自定义元素
Components 是将UI代码组织成自包含的、可重用的块的一种强大而干净的方法。他们:
- …可以表示单个控件/窗口小部件或应用程序的整个部分
- …包含它们自己的视图,并且通常(可选地)包含它们自己的视图模型
- …可以通过AMD或其他模块系统预加载,也可以(按需)异步加载
- …可以接收参数,并选择性地将更改写回参数或调用回调
- …可以组合在一起(嵌套)或从其他组件继承
- …可以轻松打包,以便在项目间重用
- …让您为配置和加载定义自己的约定/逻辑
这种模式对大型应用程序是有益的,因为它通过清晰的组织和封装简化了开发,并根据需要增量地加载应用程序代码和模板,从而帮助提高运行时性能。
自定义元素是用于消费组件的可选但方便的语法。不需要使用占位符<div>
来将绑定注入组件,您可以使用更多带有自定义元素名称的自描述性标记(例如,<voting-button>
or <product-editor>
))。淘汰赛会确保即使与IE 6等老浏览器兼容。
Example: A like/dislike widget
To get started, you can register a component using ko.components.register
(technically, registration is optional, but it’s the easiest way to get started). A component definition specifies a viewModel
and template
. For example:
要开始,您可以使用ko.components.register
注册一个组件(从技术上讲,注册是可选的,但这是最简单的方法)。组件定义指定视图模型和模板。例如
ko.components.register('like-widget', {
viewModel: function(params) {
// Data: value is either null, 'like', or 'dislike'
this.chosenValue = params.value;
// Behaviors
this.like = function() { this.chosenValue('like'); }.bind(this);
this.dislike = function() { this.chosenValue('dislike'); }.bind(this);
},
template:
'<div class="like-or-dislike" data-bind="visible: !chosenValue()">\
<button data-bind="click: like">Like it</button>\
<button data-bind="click: dislike">Dislike it</button>\
</div>\
<div class="result" data-bind="visible: chosenValue">\
You <strong data-bind="text: chosenValue"></strong> it\
</div>'
});
通常,您会从外部文件加载视图模型和模板,而不是像这样内嵌声明它们。我们稍后再谈。
现在,要使用这个组件,您可以从应用程序中的任何其他视图引用它,或者使用component
binding ,或者使用 custom element。下面是一个将它用作自定义元素的实时示例:
Source code: View
<ul data-bind="foreach: products">
<li class="product">
<strong data-bind="text: name"></strong>
<like-widget params="value: userRating"></like-widget>
</li>
</ul>
Source code: View model
function Product(name, rating) {
this.name = name;
this.userRating = ko.observable(rating || null);
}
function MyViewModel() {
this.products = [
new Product('Garlic bread'),
new Product('Pain au chocolat'),
new Product('Seagull spaghetti', 'like') // This one was already 'liked'
];
}
ko.applyBindings(new MyViewModel());
在本例中,组件在Product
view model类上同时显示和编辑一个名为userRating
的可观察属性。
Example: 根据需要,从外部文件加载 like/dislike 小部件
在大多数应用程序中,您都希望将组件视图模型和模板保存在外部文件中。如果将击倒配置为通过AMD模块加载器(如require.js)获取它们。然后,它们可以预先加载(可能是绑定/缩小),也可以根据需要增量加载。
下面是一个示例配置:
ko.components.register('like-or-dislike', {
viewModel: { require: 'files/component-like-widget' },
template: { require: 'text!files/component-like-widget.html' }
});
必要条件
为了让它发挥作用,文件files/component-like-widget.js
和 files/component-like-widget.html
必须存在。检查它们(并在.html文件中查看源代码)——您将看到,这比在定义中内联代码更干净、更方便。
此外,您还需要引用一个合适的模块加载器库(如 require.js),或者实现一个知道如何获取文件的自定义组件加载器(custom component loader)。
使用组件
现在like-or-dislike
可以像以前一样被消耗掉,使用component
binding 或者 custom element
Source code: View
<ul data-bind="foreach: products">
<li class="product">
<strong data-bind="text: name"></strong>
<like-or-dislike params="value: userRating"></like-or-dislike>
</li>
</ul>
<button data-bind="click: addProduct">Add a product</button>
Source code: View model
function Product(name, rating) {
this.name = name;
this.userRating = ko.observable(rating || null);
}
function MyViewModel() {
this.products = ko.observableArray(); // Start empty
}
MyViewModel.prototype.addProduct = function() {
var name = 'Product ' + (this.products().length + 1);
this.products.push(new Product(name));
};
ko.applyBindings(new MyViewModel());
如果在第一次单击“添加产品”之前打开浏览器开发人员工具的网络检查器,您将看到组件的 .js
/.html
文件在首次需要时按需提取,然后保留以供重复使用。