Knockoutjs 的Components 是一种自定义的组件,它以一种强大、简介的方式将你自己的ui代码组织成一种单独的、可重用的模块,自定义的组件(Component)有以下特点:

1.可以替代单独的widgit或者控制逻辑,或者你自己application的整个模块;
2.包含自己的view,通常也包含了自己的viewModel(这个viewModel也可以不进行定义)
3.可以预加载,可以通过AMD或者其他模块系统的方式根据需要异步加载
4.可以接收参数,根据需要选择性的对这些参数进行修改并返回,或者调用回调函数
5.组件可以进行组合,或者从别的组件进行继承
6.能够进行打包,跨项目复用
7.允许你定义自己的逻辑来进行js文件的配置和加载
这种模式对大型应用来讲是非常有利的,因为这种自定义组件的模式,通过清晰的组织和封装简化了开发复杂度,通过根据需要增量式的加载你自己的应用代码和模板大大提高了运行时的性能。
 
自定义元素:是一种使用自定义组件的非常便利的方式。你不必一定要用一对<div data-bind=""></div>套在你需要绑定的标签的外层来进行数据的绑定,而是用你自己描述的标记语言,比如<voting-button><product-editor>,这种形式,标签里的是你自定义的元素名称。Knockout在这一点上也兼容老版本的浏览器,IE6兼容。
 
例子一:一个 like/dislike的小插件
首先,你需要用来ko.components.register注册一个component。一个组件的定义需要有一个viewModel和一个template:
  1. ko.components.register('like-widget', {
  2. viewModel: function(params) {
  3. // Data: value is either null, 'like', or 'dislike'
  4. this.chosenValue = params.value;
  5. // Behaviors
  6. this.like = function() { this.chosenValue('like'); }.bind(this);
  7. this.dislike = function() { this.chosenValue('dislike'); }.bind(this);
  8. },
  9. template:
  10. '<div class="like-or-dislike" data-bind="visible: !chosenValue()">\
  11. <button data-bind="click: like">Like it</button>\
  12. <button data-bind="click: dislike">Dislike it</button>\
  13. </div>\
  14. <div class="result" data-bind="visible: chosenValue">\
  15. You <strong data-bind="text: chosenValue"></strong> it\
  16. </div>'
  17. });

通常情况下,你需要引入外部文件来加载viewModel和模板,而不是像上面这样写到同一个文件里。稍后我们讲解怎么以引入外部文件的方式加载viewModel和template。

现在,通过进行组件绑定(component binding)或者自定义元素的方式在你的view(通常是html文档)里使用上面的自定义组件了。
viewCode:
  1. <ul data-bind="foreach: products">
  2. <li class="product">
  3. <strong data-bind="text: name"></strong>
  4. <like-widget params="value: userRating"></like-widget>
  5. </li>
  6. </ul>
 

viewModelCode:

  1. function Product(name, rating) {
  2. this.name = name;
  3. this.userRating = ko.observable(rating || null);
  4. }
  5. function MyViewModel() {
  6. this.products = [
  7. new Product('Garlic bread'),
  8. new Product('Pain au chocolat'),
  9. new Product('Seagull spaghetti', 'like') // This one was already 'liked'
  10. ];
  11. }
  12. ko.applyBindings(new MyViewModel());
在这个例子里面,组件通过Product的viewModel中的可监控属性:userRating来进行显示、编辑。
 
例子二:从外部文件加载like/dislike组件
在大多数的应用中,一般都会将组件的viewModel和模板放在外部文件中,如果你使用require.js这样的模块加载器来配置加载knockout来获取外部ADM模块的话,那么就可以通过bundle/minified的方式来进行预加载,或者按需增量加载。
下面是一个使用require.js的配置示例:
  1. ko.components.register('like-or-dislike', {
  2. viewModel: { require: 'files/component-like-widget' },
  3. template: { require: 'text!files/component-like-widget.html' }
  4. });

需要的文件:

为了实现改组件(component)的功能,需要文件files/component-like-widget.js 和files/component-like-widget.html 。你是不是发现,这比直接在组件的定义里面包含viewModel和template要整洁、方便很多。
files/component-like-widget.js code:
  1. define(['knockout'], function(ko) {
  2. function LikeWidgetViewModel(params) {
  3. this.chosenValue = params.value;
  4. }
  5. LikeWidgetViewModel.prototype.like = function() {
  6. this.chosenValue('like');
  7. };
  8. LikeWidgetViewModel.prototype.dislike = function() {
  9. this.chosenValue('dislike');
  10. };
  11. return LikeWidgetViewModel;
  12. });

files/component-like-widget.html code:

  1. <div class="like-or-dislike" data-bind="visible: !chosenValue()">
  2. <button data-bind="click: like">Like it</button>
  3. <button data-bind="click: dislike">Dislike it</button>
  4. </div>
  5. <div class="result" data-bind="visible: chosenValue">
  6. You <strong data-bind="text: chosenValue"></strong> it.
  7. And this was loaded from an external file.
  8. </div>

现在like-or-dislike插件可以像上面的例子一样使用,使用component binding的方式,或者自定义元素的方式。

下面是源码:

view :

  1. <ul data-bind="foreach: products">
  2. <li class="product">
  3. <strong data-bind="text: name"></strong>
  4. <like-or-dislike params="value: userRating"></like-or-dislike>
  5. </li>
  6. </ul>
  7. <button data-bind="click: addProduct">Add a product</button>

viewModel:

  1. function Product(name, rating) {
  2. this.name = name;
  3. this.userRating = ko.observable(rating || null);
  4. }
  5. function MyViewModel() {
  6. this.products = ko.observableArray(); // Start empty
  7. }
  8. MyViewModel.prototype.addProduct = function() {
  9. var name = 'Product ' + (this.products().length + 1);
  10. this.products.push(new Product(name));
  11. };
  12. ko.applyBindings(new MyViewModel());

在你第一次点击“Add product” 按钮之前,打开浏览器的开发工具Network,你会发现组件的.js/.html文件第一次是按需加载的,加载之后就一直存在以备下次复用。

Knockoutjs源出处:http://knockoutjs.com/documentation/component-overview.html

Knockoutjs:Component and Custom Elements(翻译文章)的更多相关文章

  1. Web Components之Custom Elements

    什么是Web Component? Web Components 包含了多种不同的技术.你可以把Web Components当做是用一系列的Web技术创建的.可重用的用户界面组件的统称.Web Com ...

  2. window 属性:自定义元素(custom elements)

      概述 Web Components 标准非常重要的一个特性是,它使开发者能够将HTML页面的功能封装为 custom elements(自定义标签),而往常,开发者不得不写一大堆冗长.深层嵌套的标 ...

  3. HTML Custom Elements (v1)

    HTML Custom Elements (v1) https://developers.google.com/web/fundamentals/web-components/customelemen ...

  4. [大牛翻译系列]Hadoop 翻译文章索引

    原书章节 原书章节题目 翻译文章序号 翻译文章题目 链接 4.1 Joining Hadoop(1) MapReduce 连接:重分区连接(Repartition join) http://www.c ...

  5. Java 破解谷歌翻译api,可以实现程序自动化翻译文章

    1  原理:查看谷歌翻译网站,输入需要翻译的文字,选择语言得到翻译后的文字,发送异步请求参数返回结果.java使用httpclient发送请求,实现使用代码翻译文章的功能. 2  下载代码后,测试入口 ...

  6. 自定义元素(custom elements)

    记录下自定义html自定义元素的相关心得: 浏览器将自定义元素保留在 DOM 之中,但不会任何语义.除此之外,自定义元素与标准元素都一致 事实上,浏览器提供了一个HTMLUnknownElement, ...

  7. [HTML5] Render Hello World Text with Custom Elements

    Custom elements are fun technology. In this video, you will learn how to set one up and running in l ...

  8. 使用custom elements和Shadow DOM自定义标签

    具体的api我就不写 官网上面多  如果不知道这个的话也可以搜索一下 目前感觉这个还是相当好用的直接上码. <!DOCTYPE html> <html lang="en&q ...

  9. HTML Custom Elements & valid name

    HTML Custom Elements & valid name valid custom element name https://html.spec.whatwg.org/multipa ...

随机推荐

  1. Bezier(贝塞尔)曲线简介

    在计算机图形学中,Bezier曲线被广泛用于对平滑的曲线进行建模,对其有适当的了解是必要的.一条Bezier曲线由一系列控制点定义,称为曲线的阶数,由此可知,使用两个控制点()可以定义一条一阶Bezi ...

  2. Fourier分析基础(二)——由级数导出连续Fourier变换

    此处推导参考(照抄) A First Course in Wavelets with Fourier Analysis Second Edition, Albert Boggess& Fran ...

  3. 内功心法 -- Java标记接口

    写在前面的话:读书破万卷,编码如有神--------------------------------------------------------------------这篇博客主要来谈谈" ...

  4. sql查询调优之where条件排序字段以及limit使用索引的奥秘

       奇怪的慢sql 我们先来看2条sql 第一条: select * from acct_trans_log WHERE  acct_id = 1000000000009000757 order b ...

  5. JAVA_file(2)

    几种不太安全的: 1. new File(path),这个方法的路径到底在那里取决于调用java命令的起始位置定义在哪里, tomcat/bin下面的catalina.bat调用了java,所以在to ...

  6. Android jni 编程2(对基本类型一维整型数组的操作)

    参考教程和这位博主的对一维数组的处理,主要包括以下三种类型: //传入一维数组,无返回值 public native void arrayEncode(int[] arr); //传一个一维数组和数组 ...

  7. windows下搭建Nexus3私服和基于IDEA15的Maven学习笔记

    搭建Nexus私服. 首先去官网下载window下用的zip文件.https://www.sonatype.com/download-oss-sonatype. 解压之后包含下面两个文件 进入nexu ...

  8. C# 6 与 .NET Core 1.0 高级编程 - 40 ASP.NET Core(上)

    译文,个人原创,转载请注明出处(C# 6 与 .NET Core 1.0 高级编程 - 40 章  ASP.NET Core(上)),不对的地方欢迎指出与交流. 章节出自<Professiona ...

  9. SQLite基础回顾

    SQLite基础回顾 SQLite iOS中的数据存储方式 Plist(NSArray\NSDictionary) Preference(偏好设置\NSUserDefaults) NSCoding(N ...

  10. devexpress实现多行表头(复合表头),附源代码

    在许多项目中都会涉及到复合表头(多行表头),这里给大家分享一个devexpress实现多重表头的案例. 1.第一步将表格类型由默认的gridview变为bandedgridview,如图所示: 2.第 ...