cf. knockout.js
<script type="text/html" id="name-template"> ... sentence ... </script>のようにテンプレート化する
<tbody data-bind="template : {name : 'name-template', foreach: people}">というように指定してテンプレートを呼び出す
<ul data-bind="template: { name: 'seasonTemplate', foreach: seasons, as: 'season' }"></ul>
<script type="text/html" id="seasonTemplate">
<li>
<strong data-bind="text: name"></strong>
<ul data-bind="template: { name: 'monthTemplate', foreach: months, as: 'month' }"></ul>
</li>
</script>
<script type="text/html" id="monthTemplate">
<li>
<span data-bind="text: month"></span>
is in
<span data-bind="text: season.name"></span>
</li>
</script>
<script>
var viewModel = {
seasons: ko.observableArray([
{ name: 'Spring', months: [ 'March', 'April', 'May' ] },
{ name: 'Summer', months: [ 'June', 'July', 'August' ] },
{ name: 'Autumn', months: [ 'September', 'October', 'November' ] },
{ name: 'Winter', months: [ 'December', 'January', 'February' ] }
])
};
ko.applyBindings(viewModel);
</script>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>knockdown.js Ex7</title>
<style>
table{
border-collapse: collapse;
border-top: 1px solid gray;
border-right: 1px solid gray;
border-bottom: 1px solid gray;
}
th{
padding: 6px;
text-align: left;
vertical-align: top;
color: #666666;
background: #eee;
border-bottom: 1px dotted #999;
border-left: 1px solid #ccc;
}
td{
padding: 6px;
border-bottom: 1px dotted #999;
border-left: 1px solid #ccc;
}
</style>
<script type="text/html" id="name-template">
<tr data-bind="style: {'background-color' : ( $index() % 2 === 0 ? 'azure' : 'white')}">
<td data-bind="text: $index() + 1"></td>
<td data-bind="text: firstName"></td>
<td data-bind="text: lastName"></td>
<td><button data-bind="click: $parent.removePerson">delete</button></td>
</tr>
</script>
<script type="text/javascript" charset="UTF-8" src="js/lib/require.js" data-main="js/knockoutEx5_init.js"></script>
</head>
<body>
First name: <input data-bind="value: firstName"/> <br/>
Last name : <input data-bind="value: lastName"/> <br/>
<button data-bind="click: addPerson, disable: disableAddPerson">Add</button>
<table>
<thead>
<tr>
<th></th>
<th><a data-bind="click: sortByFristName">First name⇅</a></th>
<th><a data-bind="click: sortByLastName">Last name⇅</a></th>
<th></th>
</tr>
</thead>
<tbody data-bind="template : {name : 'name-template', foreach: people}">
</tbody>
</table>
</body>
</html>
/*
* アプリケーションのイニシャライザ.
*/
require.config({
// Javascript の Base Url
baseUrl: 'js/lib',
// ライブラリのパスの別名を定義する
paths: {
'app': '../',
'knockout' : 'knockout-3.2.0',
},
// AMDに対応してないモジュールを読み込む
shim: {
}
});
require(['knockout', 'app/knockoutEx5_vmodel', 'domReady!'],
function(ko, vmdl) {
ko.applyBindings(new vmdl());
}
);
/*
* アプリケーションの View Model.
*/
define(['knockout'], function(ko) {
return function appViewModel() {
var self = this;
self.firstName = new ko.observable("");
self.lastName = new ko.observable("");
self.disableAddPerson = ko.computed(function() {
return '' === self.firstName() || '' === self.lastName();
});
self.people = new ko.observableArray([
{ firstName: 'Bert', lastName: 'Bertington' },
{ firstName: 'Denise', lastName: 'Dentiste' },
{ firstName: 'Charles', lastName: 'Charlesforth' }
]);
self.sortByFirstNameAsc = 1;
self.sortByFristName = function() {
self.people.sort(function(o1, o2){
return o1.firstName.localeCompare(o2.firstName) * self.sortByFirstNameAsc;
});
self.sortByFirstNameAsc *= -1;
};
self.sortByLastNameAsc = 1;
self.sortByLastName = function() {
self.people.sort(function(o1, o2){
return o1.lastName.localeCompare(o2.lastName) * self.sortByLastNameAsc;
});
self.sortByLastNameAsc *= -1;
};
self.addPerson = function() {
var person = new Object();
person.firstName = self.firstName();
person.lastName = self.lastName();
self.firstName("");
self.lastName("");
self.people.push(person)
}
self.removePerson = function(person) {
self.people.remove(person);
}
};
});