AngulerJsとか便利なRouting機能のあるjsフレームワークは沢山ありますが
- ルーティング機能を使うだけにしてはファイルサイズが巨大すぎる
- サーバーサイドのフレームワークのルーティングとバッティングする
等色々あって利用できないプロジェクトも結構あるのではないでしょうか?
実際、僕の場合も結構ありました。
で、Routing機能単体で実装してみる事にしました。
簡単に、location.pathを元に、コントローラーを選択するようにしてみました。
ファイルパスを元にしたRouter
router
Router.ts
module util {
export class Router {
constructor(public map:any) {
}
getController():any {
if(this.map[location.pathname]){
return new this.map[location.pathname]();
}
return null;
}
}
}
ページごとに実行するコントローラー
Controllers.ts
module controllers {
export class IndexController {
showAlert():void{
alert("IndexController");
}
}
export class Sample1Controller {
showAlert():void{
alert("Sample1Controller");
}
}
export class Sample2Controller {
showAlert():void{
alert("Sample2Controller");
}
}
}
HTMLに配置
Routerのコンストラクタにmapを渡します。
今回はキーがファイルパスで、値がコントローラークラスです。
index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul>
<li><a href="/index.html">index.html</a></li>
<li><a href="/page/sample1.html">page/sample1.html</a></li>
<li><a href="/page/sample2.html">page/sample2.html</a></li>
</ul>
<script type="text/javascript" src="js/Router.js"></script>
<script type="text/javascript" src="js/Controllers.js"></script>
<script type="text/javascript">
var router = new util.Router({
"/index.html" : controllers.IndexController,
"/page/sample1.html" : controllers.Sample1Controller,
"/page/sample2.html" : controllers.Sample2Controller
});
var controller = router.getController();
controller.showAlert();
</script>
</body>
</html>
これだけで、下記のURLに応じたコントローラが呼び出されるようになります。
- localhost/index.html
- localhost/page/sample1.html
- localhost/page/sample2.html
ルーティングのルールを変えてみる
前述のRouterはファイルパスを元にルーティング処理を行いました。
今度は、URLのGETパラメータを元にルーティングを行ってみます。
GetRouterを作成
location.searchをキーにControllerの割当を行います。
Router.ts
module util {
export class Router {
constructor(public map:any) {
}
getController():any {
if(this.map[location.pathname]){
return new this.map[location.pathname]();
}
return null;
}
}
export class GetRouter extends Router{
getController():any {
if(this.map[location.search]){
return new this.map[location.search]();
}
return null;
}
}
}
GETRouterを設置
mapの内容をurlのqueryにしてみます。
get_index.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<ul>
<li><a href="/get_index.html?page=index">/get_index.html?page=index</a></li>
<li><a href="/get_index.html?page=sample1">/get_index.html?page=sample1</a></li>
<li><a href="/get_index.html?page=sample2">/get_index.html?page=sample2</a></li>
</ul>
<script type="text/javascript" src="js/Router.js"></script>
<script type="text/javascript" src="js/Controllers.js"></script>
<script type="text/javascript">
var router = new util.GetRouter({
"?page=index" : controllers.IndexController,
"?page=sample1" : controllers.Sample1Controller,
"?page=sample2" : controllers.Sample2Controller
});
var controller = router.getController();
controller.showAlert();
</script>
</body>
</html>
これで、下記URLで各コントローラーが呼び出されます
- localhost/get_index.html?page=index
- localhost/get_index.html?page=sample1
- localhost/get_index.html?page=sample2
こんな感じで応用していくと色々つぶしが利いてきます。
githabにサンプルをアップしておきました。
https://github.com/ts020/Router.js