HaxeでSPAを作ろうと思い立ちました。
Haxeで書くのでjQueryに依存しないルーティングライブラリが欲しかったのですがそういったexternが探しても見つからない。
Kazitori.jsというライブラリはexternもあるし、外部ライブラリにも依存してなくていい感じだったのですが、事後処理を登録出来ないところがネックで利用を断念…
そんな訳で自作してしまった。
(Kazitori.jsを調べた後で書き出したせいか、多くの影響をKazitori.jsから受けております。)
RouterHx
RouterHxはjavascriptまたはhaxe(jsターゲット)で利用出来るpushstate対応のrouterライブラリです。
javascriptの他のライブラリに依存することなく利用することが出来ます。
古いブラウザでは動作しません。
リンクをパーマリンクに変換するような気の利いたことも出来ません。
addEventristener
,querySelectorAll
,pushState(popState)
が使えないブラウザはごめんなさい。
ダウンロード
GitHubで公開してます
git clone https://github.com/k-motoyan/routerhx
Haxeの場合はhaxelib
からインストール出来ます
haxelib git routerhx https://github.com/k-motoyan/routerhx
基本的な使い方
Routerクラスをインスタンス化して、add
メソッドにURL、処理を持つクラス名、クラスから実行したいメソッド名を指定します。
javascriptの場合
function App() {
this.index = function() {
console.log("app index");
}
this.greet = function(message) {
console.log(message);
}
}
var router = new RouterHx();
router.add("/", "App", "index");
router.add("/greet/<message>", "App", "greet");
Haxeの場合
import routerhx.Router;
class Main {
public function new() {
var router = new Router();
router.add("/", "App", "index");
router.add("/greet/<message>", "App", "greet");
}
static function main() {
new Main();
}
}
class App {
public function index() {
trace("app index");
}
public function greet(message) {
trace(message);
}
}
pushstateしてみる
RouterHxはルーティングを定義するだけではpushStateどころか登録した処理は実行されません。
raisePushState
メソッドを実行することで、対象のセレクタをpushステート対応のエレメントに変化させます。
aタグをクリックしたらrouterに登録した処理を実行させたいといった場合のサンプルです。
javascriptの場合
var router = new RouterHx();
router.raisePushState("a", "click", "href");
Haxeの場合
import routerhx.Router;
class Main {
public function new() {
var router = new Router();
router.raisePushState("a", "click", "href");
}
static function main() {
new Main();
}
}
raisePushState
メソッドは指定したセレクタをまとめてpushState対応のエレメントに変化させるもので、
個別にrouterに登録したURLを実行した時もあると思います。
そういった場合はrun
メソッドを実行することで、routerに登録したURLを実行することが可能です。
javascriptの場合
var App = function() {
this.index = function() {
console.log("app index");
}
}
var router = new RouterHx();
router.add("/", "App", "index");
router.run("/");
Haxeの場合
import routerhx.Router;
class Main {
public function new() {
var router = new Router();
router.add("/", "App", "index");
router.run("/");
}
static function main() {
new Main();
}
}
class App {
public function index() {
trace("app index");
}
}
マイクロフレームワーク風な書き方
RouterHxはルーティングの設定の方法が2つあります。
一つ目は最初に書いたadd
メソッドにインスタンス、インスタンスから実行するメソッドを記述する方法でした。
この方法はアプリケーションの規模が大きくなった場合にコードの構造化をやりやすくします。
規模が小さいアプリケーションの場合は、addCb
メソッドに単純にコールバックを登録することでもルーティングを登録することが出来ます。
javascriptの場合
var router = new RouterHx();
router.addCb("/", function() {
console.log("index");
});
router.addCb("/greet/<message>", function(message) {
console.log(message);
});
Haxeの場合
import routerhx.Router;
class Main {
public function new() {
var router = new Router();
router.addCb("/", function() {
trace("index");
});
router.addCb("/greet/<message>", function(message) {
trace(message);
});
}
static function main() {
new Main();
}
}
RouterHxインスタンス単位での事前処理・事後処理
setBefore
、setAfter
を利用することで、RouterHxのインスタンス単位に事前処理、事後処理を登録することが可能です。
javascriptの場合
var router1 = new RouterHx();
router1.setBefore(function() {
console.log("router1 proc start.");
});
router1.setAfter(function() {
console.log("router1 proc end.");
});
var router2 = new RouterHx();
router2.setBefore(function() {
console.log("router2 proc start.");
});
router2.setAfter(function() {
console.log("router2 proc end.");
});
Haxeの場合
import routerhx.Router;
class Main {
public function new() {
var router1 = new Router(),
router2 = new Router();
router1.setBefore(_before1);
router1.setAfter(_after1);
router2.setBefore(_before2);
router2.setAfter(_after2);
}
inline function _before1(): Void {
trace("router1 proc start.");
}
inline function _after1(): Void {
trace("router1 proc end.");
}
inline function _before2(): Void {
trace("router2 proc start.");
}
inline function _after2(): Void {
trace("router2 proc end.");
}
}
RouterHxに登録したインスタンス単位の事前処理・事後処理
RouterHxに登録したインスタンスにbefore
、after
メソッドを登録しておくことでそのインスタンスのメソッド実行前・実行後に行う処理を登録しておくことが可能です。
setBefore
、setAfter
がRouterHxインスタンスのグローバルな事前処理・事後処理であるのに対して、
この方法はRouterHxに登録したインスタンス単位の事前処理・事後処理を登録することになります。
処理の順番は下記のようになります。
①setBefore
で登録した処理
②before
メソッドに記述した処理
③RouteHxのルーティングに登録した処理
④after
メソッドに記述した処理
⑤setAfter
で登録した処理
javascriptの場合
var App = function() {
this.before = function() {
console.log("app before");
};
this.index = function() {
console.log("app index");
};
this.after = function() {
console.log("app after");
};
}
var router = new RouterHx();
router.add("/", "App", "index");
Haxeの場合
import routerhx.Router;
class Main {
public function new() {
var router = new Router();
router.add("/", "App", "index");
}
static function main() {
new Main();
}
}
class App {
public function before() {
trace("app before");
}
public function index() {
trace("app index");
}
public function after() {
trace("app after");
}
}
今後の展望
作っていたら中々使い勝手いいんじゃない?と思える出来栄えになったので今後もメンテ続けて行けたらと思う。
取り敢えずは↓の実装を進めていきたいな…
-
raisePushState
って名前がおかしいので直す - オプションでURLをhash bangに切り替えられるようにする