テキストと外観の制御(Controlling text and appearance)
テキストや要素のスタイル、属性の制御に利用できるバインディングは以下の6種類が提供されています。
visible
<span data-bind="visible: messageVisible">Hello</span> <script type="text/javascript"> var vm = { messageVisible: ko.observable(true) }; ko.applyBindings(vm); </script>
text
<span data-bind="text: message"></span> <script type="text/javascript"> var vm = { message: ko.observable('KnockoutJS') }; ko.applyBindings(vm); </script>
バインディングにspanタグなどの要素を使用したくない場合は、コメント要素にバインディングを使用することも出来ます。
<!--ko text: message--><!--/ko-->
html
<div data-bind="html: content"></div> <script type="text/javascript"> var vm = { content: ko.observable('<b>KnockoutJS</b>') }; ko.applyBindings(vm); </script>
css
<span data-bind="css: {overDue: overDue}">Due Date</span> <script type="text/javascript"> var vm = { overDue: ko.observable(true) }; ko.applyBindings(vm); </script>
一つの要素に複数のクラスを設定することも出来ます。
<span data-bind="css: {overDue: overDue, selected: selected}">Due Date</span>
style
<span data-bind="style: { color : color }">Due Date</span> <script type="text/javascript"> var vm = { color: ko.observable('red') }; ko.applyBindings(vm); </script>
attr
<img src="loading.gif" data-bind="attr: { src: icon }" /> <script type="text/javascript"> var vm = { icon: ko.observable('complete.png') }; ko.applyBindings(vm); </script>
フロー制御(control flow)
DOM 構造の制御に利用できるバインディングは以下の4種類が提供されています。
foreach
<table> <tbody data-bind="foreach: issues"> <tr> <td data-bind="text: $index"></td> <td data-bind="text: summary"></td> <td data-bind="text: status"></td> </tr> </tbody> </table> <script type="text/javascript"> var vm = { issues:[ { summary: 'KnockoutJS', status: 'In Progress'}, { summary: 'Backlog', status: 'Resolved'} ] }; ko.applyBindings(vm); </script>
text バインディングと同じく、コメント要素にバインディングを使用することも出来ます。
<!--ko foreach: issues--> <span data-bind="text: summary"></span> <!--/ko-->
if / ifnot
<div data-bind="if: progress"> <img src="loading.gif" alt="loading"/> </div> <script type="text/javascript"> var vm = { progress: ko.observable(true) }; ko.applyBindings(vm); </script>
コメント要素にバインディングを使用することも出来ます。
<!--ko if: progress--> <img src="loading.gif" alt="loading" /> <!--/ko-->
with
<span data-bind="text: title"></span> <div data-bind="with:issue"> <span data-bind="text: summary"></span> <span data-bind="text: status"></span> </div> <div data-bind="with: user"> <span data-bind="text: name"></span> <span data-bind="text: age"></span> </div> <script type="text/javascript"> var vm = { title: 'Backlog Blog', issue: { summary: 'KnockoutJS', status: 'In Progress' }, user: { name: 'eguchi', age: 26 } }; ko.applyBindings(vm); </script>
上の例で with バインディングを使用しなかった場合は以下の様なコードになります。
<span data-bind="text: title"></span> <div> <span data-bind="text: issue.summary"></span> <span data-bind="text: issue.status"></span> </div> <div> <span data-bind="text: user.name"></span> <span data-bind="text: user.age"></span> </div>
フォーム要素(Working with form fields)
input や select などのフォーム要素の制御や、マウスクリックを始めとしたイベントへのイベントハンドラの設定に利用できるバインディングは以下の11種類が提供されています。
click
<span data-bind="click: showAlert">Alert</span> <script type="text/javascript"> var vm = { showAlert: function () {alert('KnockoutJS')} }; ko.applyBindings(vm); </script>
foreach バインディング内で click バインディングや event バインディングを使用した場合、関数の第一引数に foreach の配列内の対応するオブジェクトが渡されます。
<table> <tbody data-bind="foreach: issues"> <tr data-bind="click: $parent.handleClick"> <td data-bind="text: $index"> <td data-bind="text: summary"></td> <td data-bind="text: status"></td> </tr> </tbody> </table> <script type="text/javascript"> var vm = { issues:[ { summary: 'KnockoutJS', status: 'In Progress'}, { summary: 'Backlog', status: 'Resolved'} ] ,handleClick: function(data){ alert(data.summary); } }; ko.applyBindings(vm); </script>
clickBubble を設定すると、イベント伝播を止めることが出来ます。
<span data-bind="click: showAlert, clickBubble: false">Alert<span>
event
<span data-bind="event: { mouseover: showAlert }">Alert</span> <script type="text/javascript"> var vm = { showAlert: function () {alert('KnockoutJS')} }; ko.applyBindings(vm); </script>
イベント名 + ‘Bubble’ を設定すると、イベント伝播を止めることが出来ます。
<span data-bind="event: { mouseover: showAlert }, mouseoverBubble: false">Alert<span>
submit
<form data-bind="submit: post"> <input data-bind="value: message"/> <button type="submit">Submit</button> </form>
enable / disable
<input data-bind="enable: canInput"/> <script type="text/javascript"> var vm = { canInput: ko.observable(false) }; ko.applyBindings(vm); </script>
value
<input data-bind="value: message"/> <script type="text/javascript"> var vm = { message: ko.observable('KnockoutJS') }; ko.applyBindings(vm); </script>
hasFocus
<input data-bind="hasFocus: editing"/> <script type="text/javascript"> var vm = { editing: ko.observable(true) }; ko.applyBindings(vm); </script>
checked
<input type="checkbox" data-bind="checked: value"/> <script type="text/javascript"> var vm = { value: ko.observable(true) }; ko.applyBindings(vm); </script>
options
<select data-bind="options: itemList"></select> <script type="text/javascript"> var vm = { itemList: ['松','竹','梅','桃','桑','桐'] }; ko.applyBindings(vm); </script>
selectedOptions
<select data-bind="options: itemList, selectedOptions: selectedItem"></select> <span data-bind="text: selectedItem"></span> <script type="text/javascript"> var vm = { itemList: ['松','竹','梅','桃','桑','桐'], selectedItem: ko.observableArray(['梅']) }; ko.applyBindings(vm); </script>
uniqueName
テンプレート(Rendering templates)
テンプレートの定義・描画に利用できるバインディングとして template バインディングが提供されています。
パラメータで指定された名前のテンプレートに、データをバインドしてDOMツリーを追加します。テンプレートの定義は script タグ内に定義し、id 属性でテンプレート名を設定します。
<div data-bind="template: { name: 'issue-template', data: issue }"></div> <script type="text/html" id="issue-template"> <p> <span data-bind="text: summary"></span> <span data-bind="text: status"></span> </p> </script> <script type="text/javascript"> var vm = { issue: { summary: 'KnockoutJS', status: 'In Progress' } }; ko.applyBindings(vm); </script>
データに配列または observableArray を使用する場合は、data ではなく foreach でデータを指定します。
<div data-bind="template: { name: 'issueTemplate', foreach: issues }">
また、テンプレートは observable な値や関数を name に設定することで、動的に変更することが出来ます。
<div data-bind="template: { name: templateName, data: issue }"></div> <span data-bind="click: changeTemplate">change</span> <script type="text/html" id="issue-template"> <p> <span data-bind="text: summary"></span> <span data-bind="text: status"></span> </p> </script> <script type="text/html" id="issue-template2"> <ul> <li data-bind="text: summary"></li> <li data-bind="text: status"></li> </ul> </script> <script type="text/javascript"> var vm = function () { var self = this; self.templateName = ko.observable('issue-template'); self.issue = { summary: 'KnockoutJS', status: 'In Progress' }; self.changeTemplate = function(){ self.templateName('issue-template2'); } }; ko.applyBindings(new vm()); </script>
name に関数を設定した場合は、データの内容に応じてテンプレートを切り替えるといったようなことが出来ます。
<div data-bind="template: { name: templateName, data: issue }"></div> <script type="text/html" id="issue-template"> <p> <span data-bind="text: summary"></span> <span data-bind="text: status"></span> </p> </script> <script type="text/html" id="issue-template2"> <ul> <li data-bind="text: summary"></li> <li data-bind="text: status"></li> </ul> </script> <script type="text/javascript"> var vm = function () { var self = this; self.templateName = function (data) { return data.status === 'In Progress' ? 'issue-template2' : 'issue-template'; }; self.issue = { summary: 'KnockoutJS', status: 'In Progress' }; }; ko.applyBindings(new vm()); </script>