Knockoutjs:Component and Custom Elements(翻译文章)

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

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.            
  6.         // Behaviors  
  7.         this.like = function() { this.chosenValue('like'); }.bind(this);  
  8.         this.dislike = function() { this.chosenValue('dislike'); }.bind(this);  
  9.     },  
  10.     template:  
  11.         '<div class="like-or-dislike" data-bind="visible: !chosenValue()">\  
  12.             <button data-bind="click: like">Like it</button>\  
  13.             <button data-bind="click: dislike">Dislike it</button>\  
  14.         </div>\  
  15.         <div class="result" data-bind="visible: chosenValue">\  
  16.             You <strong data-bind="text: chosenValue"></strong> it\  
  17.         </div>'  
  18. });  
一般状况下,你须要引入外部文件来加载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.    
  6. function MyViewModel() {  
  7.     this.products = [  
  8.         new Product('Garlic bread'),  
  9.         new Product('Pain au chocolat'),  
  10.         new Product('Seagull spaghetti', 'like') // This one was already 'liked'  
  11.     ];  
  12. }  
  13.    
  14. 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.   
  3.     function LikeWidgetViewModel(params) {  
  4.         this.chosenValue = params.value;  
  5.     }  
  6.   
  7.     LikeWidgetViewModel.prototype.like = function() {  
  8.         this.chosenValue('like');  
  9.     };  
  10.   
  11.     LikeWidgetViewModel.prototype.dislike = function() {  
  12.         this.chosenValue('dislike');  
  13.     };  
  14.   
  15.     return LikeWidgetViewModel;  
  16.   
  17. });  
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.   
  6. <div class="result" data-bind="visible: chosenValue">  
  7.     You <strong data-bind="text: chosenValue"></strong> it.  
  8.     And this was loaded from an external file.  
  9. </div>  

 

 

如今like-or-dislike插件能够像上面的例子同样使用,使用component binding的方式,或者自定义元素的方式。html

下面是源码:java

view :git


 

  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.    
  6. function MyViewModel() {  
  7.     this.products = ko.observableArray(); // Start empty  
  8. }  
  9.    
  10. MyViewModel.prototype.addProduct = function() {  
  11.     var name = 'Product ' + (this.products().length + 1);  
  12.     this.products.push(new Product(name));  
  13. };  
  14.    
  15. ko.applyBindings(new MyViewModel());  


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

 

 

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

相关文章
相关标签/搜索