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); } }; });