(八)Knockout 组件 Components

概述 :组件和自定义元素

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.jsfiles/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文件在首次需要时按需提取,然后保留以供重复使用。

猜你喜欢

转载自www.cnblogs.com/tangge/p/10857318.html