形式 | 学習コスト | 参考文献 | View-Model連携 | 構成の定式化 | UIコンポーネント | |
knockout.js | MVVM (Model・View・ViewModel?) | 低 | 事例少(ただし本家のみで事足りる) | 双方向バインディング | なし | jQuery と連携可能 |
backbone.js | MVC2(Model・Collection・View・Router・History) | 中 | 事例豊富 | 手動 | 強力 | underscore.js/jQuery に依存 |
angular.js | MVW(Model・View・Whatever) | 大 | 事例少(本家の解説難解過ぎ) | 双方向バインディング | あり | angular-ui、ng-animate |
First name, Last name を変更して、フォーカスを移すと Full name が更新される
[~/KnockoutExam]$ tree
.
├── README.md
├── js
│ ├── knockoutEx1_init.js
│ ├── knockoutEx1_model.js
│ ├── knockoutEx1_vmodel.js
│ ├── knockoutEx2_init.js
│ ├── knockoutEx2_model.js
│ ├── knockoutEx2_vmodel.js
│ ├── knockoutEx3_init.js
│ ├── knockoutEx3_model.js
│ ├── knockoutEx3_vmodel.js
│ └── lib
│ ├── domReady.js
│ ├── jquery-grid-4.7.1
│ │ ├── i18n
│ │ │ ├── grid.locale-ar.js
│ │ │ ├── grid.locale-bg.js
│ │ │ ├ ...
│ │ │ └── grid.locale-vi.js
│ │ ├── jquery.jqGrid.min.js
│ │ └── ui.jqgrid.css
│ ├── jquery-ui-1.11.3
│ │ ├── external
│ │ │ └── jquery
│ │ │ └── jquery.js
│ │ ├── images
│ │ │ ├── ui-icons_444444_256x240.png
│ │ │ ├── ui-icons_555555_256x240.png
│ │ │ ├── ui-icons_777620_256x240.png
│ │ │ ├── ui-icons_777777_256x240.png
│ │ │ ├── ui-icons_cc0000_256x240.png
│ │ │ └── ui-icons_ffffff_256x240.png
│ │ ├── index.html
│ │ ├── jquery-ui.css
│ │ ├── jquery-ui.js
│ │ ├── jquery-ui.min.css
│ │ ├── jquery-ui.min.js
│ │ ├── jquery-ui.structure.css
│ │ ├── jquery-ui.structure.min.css
│ │ ├── jquery-ui.theme.css
│ │ └── jquery-ui.theme.min.css
│ ├── knockout-3.2.0.js
│ ├── knockout-es5.js
│ └── require.js
├── knockoutEx1_HelloKo.html
├── knockoutEx2_Ko+jQuery.html
└── knockoutEx3_Ko+jqGrid.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Hello knockdown.js</title>
<!--
require.js (http://requirejs.org/) を使って MVC のコードを分離する。
この HTML は、View層。Controller を require.js で読み込む。
Model と knockout.js などの依存ライブラリは、Controller から読み込む。
※ require.js を使わずに knockout.js のみでアプリをつくる事もできる
-->
<script type="text/javascript" charset="UTF-8" src="js/lib/require.js" data-main="js/knockoutEx1_init.js"></script>
</head>
<body>
<p>First name: <input data-bind="value: firstName" title="個人名を入力してください" /></p>
<p>Last name : <input data-bind="value: lastName" title="姓を入力してください" /></p>
<p>Full name : <strong data-bind="text: fullName"></strong></p>
<button data-bind='click: registerClick, disable: isEnableRegister'>Search</button>
</body>
</html>
/*
* アプリケーションのイニシャライザ.
* -----------------------------------------------------------------------------
* HTML から呼び出されるモジュールは
* require([mod1, mod2], function(if1, if2) {
* // 処理
* }
* と記述する。
*
* 第一引数は、依存するライブラリ名。
* 第二引数は、画面の初期化を行う処理で、その引数は依存するライブラリ
* のインタフェースオブジェクト。
*
* 依存するライブラリは、AMD に準拠している必要がある。
* AMD に関しては knockoutEx1_model を参照してね
*/
require.config({
// Javascript の Base Url
baseUrl: 'js/lib',
// ライブラリのパスの別名を定義する
paths: {
'app': '../',
'knockout': 'knockout-3.2.0'
},
// AMDに対応してないモジュールを読み込む
shim: {
}
});
require(['knockout', 'app/knockoutEx1_vmodel', 'app/knockoutEx1_model', 'domReady!'],
function(ko, vmdl, mdl) {
ko.applyBindings(new vmdl(new mdl()));
}
);
/*
* アプリケーションの View Model.
*
* require から呼び出されるモジュールは
* define([mod1, mod2], function(if1, if2) {
* return function ifObj() {
* var _name = "";
* this.getName = function() { return _name; };
* this.setName = function(name) { _name = name; };
* };
* }
* と記述する。
*
* これは、AMD ((Asynchronous Module Definition) に準拠している
* モジュール定義。
* 第一引数は、依存するライブラリ名。
* 第二引数は、インタフェースオブジェクトを作成する処理で、引数は
* 依存ライブラリのインタフェースオブジェクト。
*/
define(['knockout'], function(ko) {
return function appViewModel(mdl) {
this.firstName = ko.observable(mdl.firstName);
this.lastName = ko.observable(mdl.lastName);
/**
* フルネーム.
*/
this.fullName = ko.computed(function() {
return this.firstName() + " " + this.lastName().toUpperCase();
}, this);
/**
* 登録ボタンクリック時の処理.
*/
this.registerClick = function() {
// View Model を Model に書き戻す
mdl.firstName = this.firstName();
mdl.lastName = this.lastName();
// 登録処理 (本当はサーバーアクセス)
alert(JSON.stringify(mdl));
};
/**
* 登録ボタンの有効化フラグ.
*/
this.isEnableRegister = ko.computed(function() {
return '' === this.firstName() || '' === this.lastName();
}, this);
};
});
/*
* アプリケーションの Model.
*/
define(function() {
return function appModel() {
this.firstName = 'Bert';
this.lastName = 'Simpson';
};
});