はじめに
前に「Knockout.js は画面を切り替える手段を提供していない」っていうことをブログに書いたら
id:iakio
tutorialの中にはsammy.jsと連携してブラウザの履歴を使う例がありますね
http://learn.knockoutjs.com/#/?tutorial=webmail
っていうブクマコメントがありました。
Sammy って何?
location.hash を使ったルーティング機能を提供する、Sinatra ライクな JavaScript フレームワークとのこと。
README に書かれているサンプルコードがこちら。
$.sammy(function() { this.get('#/', function() { $('#main').text('Welcome!'); }); });
たしかに Sinatra に似ていますね。
ソースコードをみた感じでは、location.hash が変わったら、登録したルートの中からマッチするものを探して、結び付けられている関数を実行しているみたいです。
Sammy で遊んでみます
サンプルコードは全部コピペで動くはずです。
ページを移動してみる
<!DOCTYPE html> <html> <head> <title>Sammy Sample</title> </head> <body> <div id="main"></div> <ul> <li><a href="#/kagawa">Kagawa</a></li> <li><a href="#/miyaichi">Miyaichi</a></li> <li><a href="#/honda">Honda</a></li> </ul> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script type="text/javascript" src="https://github.com/quirkey/sammy/raw/master/lib/min/sammy-latest.min.js"></script> <script type="text/javascript"> var app = Sammy(function() { this.get("#/kagawa", function() { $("#main").text("Hello, Kagawa."); }); this.get("#/miyaichi", function() { $("#main").text("Hello, Miyaichi."); }); this.get("#/honda", function() { $("#main").text("Hello, Honda."); }); }); app.run(); </script> </body> </html>
Sinatra 同様、ルートは HTTP メソッドと URL マッチングパターンがペアになっています。ルートは無名関数に結び付けられています。上記は get の例。
名前付きパラメータを取得してみる
<!DOCTYPE html> <html> <head> <title>Sammy Sample</title> </head> <body> <div id="main"></div> <ul> <li><a href="#/kagawa">Kagawa</a></li> <li><a href="#/miyaichi">Miyaichi</a></li> <li><a href="#/honda">Honda</a></li> </ul> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script type="text/javascript" src="https://github.com/quirkey/sammy/raw/master/lib/min/sammy-latest.min.js"></script> <script type="text/javascript"> var app = Sammy(function() { this.get("#/:name", function() { $("#main").text("Hello, " + this.params["name"] + "."); }); }); app.run(); </script> </body> </html>
ルートのパターンは名前付きパラメータを含むことができ、params で取得できます。
POST を処理してみる
<!DOCTYPE html> <html> <head> <title>Sammy Sample</title> </head> <body> <div id="main"></div> <form method="POST" action="#/hello"> <label for="name">name</label> <input type="text" name="name" /> <input type="submit" value="greet" /> </form> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script type="text/javascript" src="https://github.com/quirkey/sammy/raw/master/lib/min/sammy-latest.min.js"></script> <script type="text/javascript"> var app = Sammy(function() { // POST メソッドを処理する this.post("#/hello", function() { // this.params から POST パラメータを取り出せる // this は Sammy オブジェクト $("#main").text("Hello, " + this.params["name"]); }); }); app.run(); </script> </body> </html>
POST メソッドのリクエストを処理するルートも登録できます。form の submit ボタンをクリックすると、ルートに結び付けられた関数が実行されました。なんかヘンな感じ。
リダイレクトしてみる
<!DOCTYPE html> <html> <head> <title>Sammy Sample</title> </head> <body> <div id="main"></div> <ul> <li><a href="#/greet/kagawa">Kagawa</a></li> <li><a href="#/greet/miyaichi">Miyaichi</a></li> <li><a href="#/greet/honda">Honda</a></li> </ul> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script type="text/javascript" src="https://github.com/quirkey/sammy/raw/master/lib/min/sammy-latest.min.js"></script> <script type="text/javascript"> var app = Sammy(function() { this.get("#/hello/:name", function() { $("#main").text("Hello, " + this.params["name"] + "."); }); this.get("#/greet/:name", function() { // 他のルートにリダイレクトする this.redirect("#/hello/" + this.params["name"]) }); }); app.run(); </script> </body> </html>
redirect メソッドで、他のルートを呼び出せます。POST メソッドのリクエストを処理した後にリダイレクト、というお馴染みの処理で使いそう。
ヘルパーを定義してみる
<!DOCTYPE html> <html> <head> <title>Sammy Sample</title> </head> <body> <div id="main"></div> <ul> <li><a href="#/kagawa">Kagawa</a></li> <li><a href="#/miyaichi">Miyaichi</a></li> <li><a href="#/honda">Honda</a></li> </ul> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script> <script type="text/javascript" src="https://github.com/quirkey/sammy/raw/master/lib/min/sammy-latest.min.js"></script> <script type="text/javascript"> var app = Sammy(function() { // ヘルパーを定義できる // ヘルパーはルートとテンプレート内で利用可能 this.helpers({ hello: function(name) { return "Hello, " + name + "."; } }); this.get("#/:name", function() { var name = this.params["name"]; var message = this.hello(name); $("#main").text(message); }); }); app.run(); </script> </body> </html>
helpers にヘルパーを定義したオブジェクトを渡しています。定義したヘルパーはルートに結びつけた関数の中で使えます。
Knockout.js で使いそうなのはこんなところかな
他にも、テンプレートを描画したり、キャッシュが使えたり出来るみたいです。使いやすいから、JavaScript で Single Page Application を作るときの選択肢として有力じゃないでしょうか。
今度、Knockout.js と Sammy を組み合わせてみようと思います。