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:
- ko.components.register('like-widget', {
- viewModel: function(params) {
-
- this.chosenValue = params.value;
-
-
- 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>'
- });
一般狀況下,你須要引入外部文件來加載viewModel和模板,而不是像上面這樣寫到同一個文件裏。稍後咱們講解怎麼以引入外部文件的方式加載viewModel和template。
如今,經過進行組件綁定(component binding)或者自定義元素的方式在你的view(一般是html文檔)裏使用上面的自定義組件了。
viewCode:
- <ul data-bind="foreach: products">
- <li class="product">
- <strong data-bind="text: name"></strong>
- <like-widget params="value: userRating"></like-widget>
- </li>
- </ul>
viewModelCode:
- 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')
- ];
- }
-
- ko.applyBindings(new MyViewModel());
在這個例子裏面,組件經過Product的viewModel中的可監控屬性:userRating來進行顯示、編輯。
例子二:從外部文件加載like/dislike組件
在大多數的應用中,通常都會將組件的viewModel和模板放在外部文件中,若是你使用require.js這樣的模塊加載器來配置加載knockout來獲取外部ADM模塊的話,那麼就能夠經過bundle/minified的方式來進行預加載,或者按需增量加載。
下面是一個使用require.js的配置示例:
- ko.components.register('like-or-dislike', {
- viewModel: { require: 'files/component-like-widget' },
- template: { require: 'text!files/component-like-widget.html' }
- });
須要的文件:
- define(['knockout'], function(ko) {
-
- function LikeWidgetViewModel(params) {
- this.chosenValue = params.value;
- }
-
- LikeWidgetViewModel.prototype.like = function() {
- this.chosenValue('like');
- };
-
- LikeWidgetViewModel.prototype.dislike = function() {
- this.chosenValue('dislike');
- };
-
- return LikeWidgetViewModel;
-
- });
files/component-like-widget.html code:
- <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.
- And this was loaded from an external file.
- </div>
如今like-or-dislike插件能夠像上面的例子同樣使用,使用component binding的方式,或者自定義元素的方式。html
下面是源碼:java
view :git
- <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>
viewModel:瀏覽器
- function Product(name, rating) {
- this.name = name;
- this.userRating = ko.observable(rating || null);
- }
-
- function MyViewModel() {
- this.products = ko.observableArray();
- }
-
- MyViewModel.prototype.addProduct = function() {
- var name = 'Product ' + (this.products().length + 1);
- this.products.push(new Product(name));
- };
-
- ko.applyBindings(new MyViewModel());
在你第一次點擊「Add product」 按鈕以前,打開瀏覽器的開發工具Network,你會發現組件的.js/.html文件第一次是按需加載的,加載以後就一直存在以備下次複用。app
Knockoutjs源出處:http://knockoutjs.com/documentation/component-overview.html異步