目次
本記事はknockout.jsの公式サイトにある以下のチュートリアルを実施した備忘録です。 learn.knockoutjs.com
Step1
メールボックスのナビゲーションバーを表示するサンプルプログラム
サンプルコード
cssバインディングを利用して選択したフォルダに対してclass="selected"を動的に設定している。
※実際のサンプルコードでは内部的にCSSが適用されるためきれいにスタイリングされているが本サンプルプログラムはCSSを適用していないためご了承ください。
sample.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript" src="../../lib/knockout-3.2.0.js"></script> <script type="text/javascript" src="sample.js" defer="defer"></script> <title></title> </head> <body> <ul class="folders" data-bind="foreach: folders"> <li data-bind="text: $data, css: {selected: $data == $root.chosenFolderId()}, click: $root.goToFolder"></li> </ul> </body> </html>
sample.js
function WebmailViewModel() { // Data var self = this; self.folders = ['Inbox', 'Archive', 'Sent', 'Spam']; self.chosenFolderId = ko.observable(); self.goToFolder = function(folder) { self.chosenFolderId(folder); }; }; ko.applyBindings(new WebmailViewModel());
Step2
メールクライアント構築にてメールボックスの内容を取得して表形式で表示するサンプルプログラム
サンプルコード
クリックするとgoToFolder()の引数に選択されたfolderIdが渡るためフォルダごとに取得してくるデータを振り分けることができる data-bindにwithバインディングを指定することで指定したViewModelにバインドさせることができるため、そのViewModelに定義されているプロパティをそのまま呼び出せる。
※実際のサンプルコードでは内部的に/mailインタフェースを用意しているためデータが取得できるが、 本サンプルコードでは用意していないためそのまま使用しても動作しませんのでご了承ください。
sample.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript" src="../../lib/knockout-3.2.0.js"></script> <script type="text/javascript" src="sample.js" defer="defer"></script> <title></title> </head> <body> <ul class="folders" data-bind="foreach: folders"> <li data-bind="text: $data, css: {selected: $data == $root.chosenFolderId()}, click: $root.goToFolder"></li> </ul> <table class="mails" data-bind="with: chosenFolderData"> <thead> <tr> <th>From</th> <th>To</th> <th>Subject</th> <th>Date</th> </tr> </thead> <tbody data-bind="foreach: mails"> <tr> <td data-bind="text: from"></td> <td data-bind="text: to"></td> <td data-bind="text: subject"></td> <td data-bind="text: date"></td> </tr> </tbody> </table> </body> </html>
sample.js
function WebmailViewModel() { var self = this; self.folders = ['Inbox', 'Archive', 'Sent', 'Spam']; self.chosenFolderId = ko.observable(); self.chosenFolderData = ko.observable(); self.goToFolder = function(folder) { self.chosenFolderId(folder); $.get('/mail', { folder: folder }, self.chosenFolderData); }; self.goToFolder('Inbox'); }; ko.applyBindings(new WebmailViewModel());
Step3
個々のメールの内容を表示する機能を追加したサンプルプログラム
サンプルコード
htmlバインディング(data-bind="html: ~")を利用することでメール内容の改行などをきれいに表示することができる。 ko.observable()を設定したプロパティにnullを設定するとそのデータは表示されないことが分かった。
※実際のサンプルコードでは内部的に/mailインタフェースを用意しているためデータが取得できるが、 本サンプルコードでは用意していないためそのまま使用しても動作しませんのでご了承ください。
sample.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript" src="../../lib/knockout-3.2.0.js"></script> <script type="text/javascript" src="sample.js" defer="defer"></script> <title></title> </head> <body> <ul class="folders" data-bind="foreach: folders"> <li data-bind="text: $data, css: {selected: $data == $root.chosenFolderId()}, click: $root.goToFolder"></li> </ul> <table class="mails" data-bind="with: chosenFolderData"> <thead> <tr> <th>From</th> <th>To</th> <th>Subject</th> <th>Date</th> </tr></thead> <tbody data-bind="foreach: mails"> <tr data-bind="click: $root.goToMail"> <td data-bind="text: from"></td> <td data-bind="text: to"></td> <td data-bind="text: subject"></td> <td data-bind="text: date"></td> </tr> </tbody> <div class="viewMail" data-bind="with: chosenMailData"> <div class="mailInfo"> <h1 data-bind="text: subject"></h1> <p> <label>From</label>: <span data-bind="text: from"></span> </p> <p> <label>To</label>: <span data-bind="text: to"></span> </p> <p><label>Date</label>: <span data-bind="text: date"></span></p> </div> <p class="message" data-bind="html: messageContent" /> </div> </table> </body> </html>
sample.js
function WebmailViewModel() { var self = this; self.folders = ['Inbox', 'Archive', 'Sent', 'Spam']; self.chosenFolderId = ko.observable(); self.chosenFolderData = ko.observable(); self.chosenMailData = ko.observable(); self.goToFolder = function(folder) { self.chosenFolderId(folder); self.chosenMailData(null); $.get('/mail', { folder: folder }, self.chosenFolderData); }; self.goToMail = function(mail){ self.chosenFolderId(mail.folder); self.chosenFolderData(null); $.get("/mail", { mailId: mail.id }, self.chosenMailData); }; self.goToFolder('Inbox'); }; ko.applyBindings(new WebmailViewModel());
Step4
Sammy.jsを利用したクライアントサイドのルーティング実装を行ったサンプルプログラム
サンプルコード
Sammy.jsを利用することでクライアント側でのルーティング設定が行えることが分かった。 それ以外のルーティングライブラリと組み合わせても行えるはず。
※実際のサンプルコードでは内部的に/mailインタフェースを用意しているためデータが取得できるが、 本サンプルコードでは用意していないためそのまま使用しても動作しませんのでご了承ください。
sample.html
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <script type="text/javascript" src="../../lib/knockout-3.2.0.js"></script> <script type="text/javascript" src="sample.js" defer="defer"></script> <title></title> </head> <body> <script src="/scripts/lib/sammy.js" type="text/javascript"></script> <ul class="folders" data-bind="foreach: folders"> <li data-bind="text: $data, css: {selected: $data == $root.chosenFolderId()}, click: $root.goToFolder"></li> </ul> <table class="mails" data-bind="with: chosenFolderData"> <thead> <tr> <th>From</th> <th>To</th> <th>Subject</th> <th>Date</th> </tr> </thead> <tbody data-bind="foreach: mails"> <tr data-bind="click: $root.goToMail"> <td data-bind="text: from"></td> <td data-bind="text: to"></td> <td data-bind="text: subject"></td> <td data-bind="text: date"></td> </tr> </tbody> <div class="viewMail" data-bind="with: chosenMailData"> <div class="mailInfo"> <h1 data-bind="text: subject"></h1> <p> <label>From</label>: <span data-bind="text: from"></span> </p> <p> <label>To</label>: <span data-bind="text: to"></span> </p> <p> <label>Date</label>: <span data-bind="text: date"></span> </p> </div> <p class="message" data-bind="html: messageContent" /> </div> </table> </body> </html>
sample.js
function WebmailViewModel() { var self = this; self.folders = ['Inbox', 'Archive', 'Sent', 'Spam']; self.chosenFolderId = ko.observable(); self.chosenFolderData = ko.observable(); self.chosenMailData = ko.observable(); self.goToFolder = function(folder) { location.hash = folder }; self.goToMail = function(mail) { location.hash = mail.folder + '/' + mail.id }; Sammy(function() { this.get('#:folder', function() { self.chosenFolderId(this.params.folder); self.chosenMailData(null); $.get("/mail", { folder: this.params.folder }, self.chosenFolderData); }); this.get('#:folder/:mailId', function() { self.chosenFolderId(this.params.folder); self.chosenFolderData(null); $.get("/mail", { mailId: this.params.mailId }, self.chosenMailData); }); this.get('', function() {this.app.runRoute('get', '#Inbox')}); }).run(); }; ko.applyBindings(new WebmailViewModel());
記事トップは以下になります。