(Knockout版本:3.4.1 )
KO的組件主要從如下四個部分進行詳細介紹:javascript
1.組件的定義和註冊
2.組件綁定
3.使用自定義元素
4.自定義組件加載器(高級)html
1.經過"視圖模型"、"模版"配對註冊組件java
--1.1 指定視圖模型的方法
----1.1.1 構造函數
----1.1.2 對象實例
----1.1.3 創造視圖模型的工廠函數
----1.1.4 AMD模塊,其值描述了一個視圖模型node
--1.2 指定模版的方法
----1.2.1 已存在元素的ID
----1.2.2 已存在元素的實例
----1.2.3 HTML字符串
----1.2.4 包含許多DOM節點的數組
----1.2.5 文檔片斷
----1.2.6 AMD模塊,其值描述了一個模版web
2.Knockout怎樣經過AMD加載組件數組
--2.1 AMD模塊爲按需加載瀏覽器
3.經過一個AMD模塊註冊組件dom
--3.1 推薦的AMD組件模塊的定義方式函數
function SomeComponentViewModel(params) { // 'params' is an object whose key/value pairs are the parameters // passed from the component binding or custom element. this.someProperty = params.something; } SomeComponentViewModel.prototype.doSomething = function() { ... }; ko.components.register('my-component', { viewModel: SomeComponentViewModel, template: ... });
Knockout將會調用這個構造函數並生成一個實例做爲視圖模型,其中params參數在組件調用的時候傳入。post
直接傳遞一個對象實例做爲視圖模型,全部使用這個對象的組件共享這一個實例。假定對象實例爲modelInstance,注意傳入方法爲:viewModel: {instance: modelInstance}
若是建立這個視圖模型須要取得一些組件調用的信息,那麼就採起這從模式定義視圖模型。
ko.components.register('my-component', { viewModel: { createViewModel: function(params, componentInfo) { // - 'params'是組件調用時傳入的對象 // - 'componentInfo.element'是組件注入的元素,當createViewModel方 // 法被調用時,組件已被注入到元素中,但尚未發生綁定。 // - 'componentInfo.templateNodes'是一個包含了組件調用時內部的DOM節 // 點的數組。 // 經過本身定義的構造函數返回一個實例 return new MyViewModel(params); } }, template: ... });
注意,操做DOM最好只經過自定義綁定,而不要經過componentInfo.element進行一些操做DOM的行爲。
componentInfo.templateNodes在咱們須要控制組件輸出的節點時會起到做用。
若是使用了AMD模塊加載器,好比(require.js),可使用模塊加載器直接加載AMD模塊做爲視圖模型。
ko.components.register('my-component', { viewModel: { require: 'some/module/name' }, template: ... });
加載的AMD模塊只要按照1.1.1,1.1.2,1.1.3三種方式中的一種提供模塊(即returns)就能夠了。另外還有一種通常不會用到的方式AMD模塊的return爲 return { module: 'some/other/module' }
,這種方式將會加載其它模塊。
<template id='my-component-template'> <h1 data-bind='text: title'></h1> <button data-bind='click: doSomething'>Click me right now</button> </template> ko.components.register('my-component', { template: { element: 'my-component-template' }, viewModel: ... });
指定一個已存在元素的ID便可,ID所對應元素自己不會被做爲模版的元素傳入,其內部節點會做爲模版被傳入。推薦使用例子裏的< template>標籤,別的標籤也能夠,但瀏覽器不識別template標籤因此它不會被渲染收到影響,另外語義也比較清晰。
相似於傳入ID,只是此次傳入的是元素實例。
ko.components.register('my-component', { template: '<h1 data-bind="text: title"></h1>\ <button data-bind="click: doSomething">Clickety</button>', viewModel: ... });
當咱們從別處取得一些字符串來生成模版時(好比AMD),這個方法頗有用。
var myNodes = [ document.getElementById('first-node'), document.getElementById('second-node'), document.getElementById('third-node') ]; ko.components.register('my-component', { template: myNodes, viewModel: ... });
這些節點會依次做爲組件模版被複制渲染出來。
能夠傳一個AMD模塊,這個模塊的返回值是以上模版的任一種類型均可以。
2.Knockout怎樣經過AMD加載組件
當爲視圖模型和模版傳入require聲明時:
ko.components.register('my-component', { viewModel: { require: 'some/module/name' }, template: { require: 'text!some-template.html' } });
這些AMD模塊被加載,實際上相似於使用了require(['some/module/name'], callback)
和require(['text!some-template.html'], callback)
。KO加載這些模塊有三個須要注意的點:
*KO並不嚴格要求使用require.js,任何其它的AMD模塊加載器均可以使用。
*KO並不影響加載模塊的路徑,路徑仍然徹底由所用的AMD加載器決定。
*KO並不關心所加載的模塊是不是暴露了全局變量名稱的模塊。
好比一個組件寫在了一個綁定了if指令的標籤中,那只有if對應的值真,組件模塊才加載,不然不加載。若是組件模塊已經加載過了, 那麼將再也不發送HTTP請求來請求模塊,而是預加載以前存下來的模塊。
只要AMD模塊返回的是以上任意一種合法的模塊配置就能夠做爲一個有效的組件模塊,可是有一種推薦的組件模塊定義方法:
// - 使用這種模式定義模塊的優勢在於 // - 引入只須要一個require聲明 // - 能夠被require.js的r.js打包 define(['knockout', 'text!./my-component.html'], function(ko, htmlString) { function MyComponentViewModel(params) { // 在這裏設置屬性等 } // 使用原型定義公共方法 MyComponentViewModel.prototype.doSomething = function() { ... }; // 返回組件的定義 return { viewModel: MyComponentViewModel, template: htmlString }; });
這樣定義的組件模塊,調用方法爲:ko.components.register('my-component', { require: 'path/my-component' });
。一個組件模塊由兩個文件組成,一個視圖模型(path/my-component.js)和一個模版(path/my-component.html),建立天然,維護方便。