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. 微信面试题-获取元素的最终background-color

    一.题目  用JS代码求出页面上一个元素的最终的background-color,不考虑IE浏览器,不考虑元素float情况. 二.题目解析  1.考察底层JavaScript基础  前端开发,日常最 ...

  2. esri-leaflet入门教程(1)-leaflet介绍

    esri-leaflet入门教程(1)-esri leaflet介绍 by 李远祥 关于leaflet,可能很多人比较陌生,如果搭上esri几个字母,可能会有更多的人关注.如果没有留意过leaflet ...

  3. java socket初步学习一 ( tcp)

    Java socket通信程序: 第一版本: 实现功能: 服务器地址:127.0.0.1  端口:5050 客户机:端口5050 客户端发送字符:“t” 服务器接收到该字符并回复:“r” 流程: 建立 ...

  4. javascript之自增自减典型运算(易错)

    JavaScript“自增”运算符与表达式 递增运算符(++)是一个一元运算符,该运算符可以将操作数进行递增操作,即每次增加1.递增运算符要求其操作数必须是变量.对象中的某个属性或数组中的某个元素,并 ...

  5. 关于Android中为什么主线程不会因为Looper.loop()里的死循环卡死?引发的思考,事实可能不是一个 epoll 那么 简单。

    ( 转载请务必标明出处:http://www.cnblogs.com/linguanh/, 本文出自:[林冠宏(指尖下的幽灵)的博客]) 前序 本文将会把一下三个问题阐述清楚以及一个网上的普遍观点的补 ...

  6. 微信公众号平台接口开发:基础支持,获取access_token

    新建Asp.net MVC 4.0项目 WeChatSubscript是项目UI层 WeChatTools是封装操作访问公众号接口的一些方法类库 获取AccssToken 我们要的得到AccessTo ...

  7. 给ubuntu安装VNC远程桌面

    (只有背景,没有菜单栏问题没有解决)Virtual Network Computing(VNC)是进行远程桌面控制的一个软件.客户端的键盘输入和鼠标操作通过网络传输到远程服务器,控制服务器的操作.服务 ...

  8. RadAsm使用

    RadASM 命令行语法 DelCheck,Out,Command,F1[,F2[,Fx]]   DelCheck   执行命令前要清除的文件,不使用时设为0  Out      一般指定为O,所有信 ...

  9. php新建数据库对象 基础知识

    数据访问 结合html 数据库 PHP面向对象的方式函数的方式 1建立通道 MySQLi 类通过构造函数造出 连接数据库地址 uesername 连接用户名 passwd dbname port so ...

  10. 关于 <textarea ></textarea >标签在苹果微信浏览器出现 内阴影

    解决方法:(去除浏览器默认的样式元素) textarea  { box-shadow:0px 0px 0px rgba(0,0,0,0); -webkit-appearance:none; }