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. Grunt + Bower—前端构建利器

    目前比较流行的WEB开发的趋势是前后端分离.前端采用重量级的Javascript框架,比如Angular,Ember等,后端采用restful API的Web Service服务,通过JSON格式进行 ...

  2. 【js 编程艺术】小制作一

    最近在看js编程艺术,照葫芦画瓢,做了一个小网页.作为一枚前端渣渣,遇到了好多坑,在这里就不提了. 首先是html代码 /*gallery.html*/<!DOCTYPE html> &l ...

  3. 开源OSS.Social微信项目解析

    ​前言:OSS.Social是个开源的社交网站接口集成项目,当前也有很多其他不错的项目,不过始终没有我想要的那种简单清晰,只能撸起袖子,从头打造一个.当前正在进行的是对微信项目的开发,这里把对接口的整 ...

  4. LPC4370使用学习:GPIO的引脚功能使用,和12864OLED模拟I2C驱动

    一: 手中有块LPC4370的开发板,因为便宜,所以引脚引出的不多,而且只有基本的底板资源驱动代码和例程. 看着手册和例程看了老半天,写程序写了半天,结果GPIO老是驱动不起来,因为引脚配置寄存器中有 ...

  5. 列存储段消除(ColumnStore Segment Elimination)

    列存储索引是好的!对于数据仓库和报表工作量,它们是真正的性能加速器.与聚集列存储结合,你会在常规行存储索引(聚集索引,非聚集索引)上获得巨大的压缩好处.而且创建聚集列存储索引非常简单: CREATE ...

  6. java_JDBC(2)

    1.Statement 每次执行sql语句,数据库都要执行sql语句的编译 ,最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement. 2.PreparedStatemen ...

  7. B. Pasha and Phone

    B. Pasha and Phone time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  8. iOS开发~制作同时支持armv7,armv7s,arm64,i386,x86_64的静态库.a

    一.概要 平时项目开发中,可能使用第三方提供的静态库.a,如果.a提供方技术不成熟,使用的时候就会出现问题,例如: 在真机上编译报错:No architectures to compile for ( ...

  9. 解析jQuery中extend方法--源码解析以及递归的过程《二》

    源码解析 在解析代码之前,首先要了解extend函数要解决什么问题,以及传入不同的参数,会达到怎样的效果.extend函数内部处理传入的不同参数,返回处理后的对象. extend函数用来扩展对象,增加 ...

  10. linux文件和目录权限

    linux系统文件和目录的权限说明 文件权限是Linux系统的第一道安全防线,基本的权限有读取(r).写入(w)和执行(x): 文件访问模式 读取:用户能够读取文件信息,查看文件内容. 写入:用户可以 ...