バックボーンを使用して、現在のルートの名前を取得することは可能ですか?ルート変更イベントにバインドする方法は知っていますが、変更間の別の時間に現在のルートを特定できるようにしたいと考えています。
バックボーンを使用して、現在のルートの名前を取得することは可能ですか?ルート変更イベントにバインドする方法は知っていますが、変更間の別の時間に現在のルートを特定できるようにしたいと考えています。
回答:
アプリケーションでルーターをインスタンス化した場合、次の行は現在のフラグメントを返します。
Backbone.history.getFragment();
"[...]履歴は、(フレームごとの)グローバルルーターとして機能し、hashchangeイベントまたはpushStateを処理し、適切なルートを照合し、コールバックをトリガーします。これらのいずれかを自分で作成する必要はありません。参照を使用する必要がありますルートを持つルーターを利用する場合に自動的に作成されるBackbone.historyへ。[...] "
そのフラグメントにバインドされた関数の名前が必要な場合は、ルーターのスコープ内で次のようにすることができます。
alert( this.routes[Backbone.history.getFragment()] );
または、ルーターの外からこのように:
alert( myRouter.routes[Backbone.history.getFragment()] );
Backbone.history.getFragment()
であるため、使用することBackbone.history.fragment
をお勧めします。
Robertの答えは興味深いですが、悲しいことに、ハッシュがルートで定義されたとおりである場合にのみ機能します。例えばあなたがいる場合はルート持っているuser(/:uid)
場合は、それが一致しませんBackbone.history.fragment
いずれかである"user"
か、"user/1"
(そのような経路のための2つの最も明白なユースケースである両方)。言い換えると、ハッシュが正確に"user(/:uid)"
(ほとんどない)場合にのみ、適切なコールバック名を見つけます。
この機能が必要だったので、HistoryオブジェクトとRouterオブジェクトが適切なコールバックをトリガーするために定義されたルートと現在のフラグメントを照合するために使用するコードの一部を再利用Backbone.Router
する- current
関数でを拡張しました。私のユースケースでは、オプションのパラメーターを使用しますroute
。これをtrueに設定すると、ルートに定義された対応する関数名が返されます。それ以外の場合は、現在のハッシュフラグメントをから返しますBackbone.History.fragment
。
バックボーンルーターを初期化およびセットアップする既存のExtendにコードを追加できます。
var Router = new Backbone.Router.extend({
// Pretty basic stuff
routes : {
"home" : "home",
"user(:/uid)" : "user",
"test" : "completelyDifferent"
},
home : function() {
// Home route
},
user : function(uid) {
// User route
},
// Gets the current route callback function name
// or current hash fragment
current : function(route){
if(route && Backbone.History.started) {
var Router = this,
// Get current fragment from Backbone.History
fragment = Backbone.history.fragment,
// Get current object of routes and convert to array-pairs
routes = _.pairs(Router.routes);
// Loop through array pairs and return
// array on first truthful match.
var matched = _.find(routes, function(handler) {
var route = handler[0];
// Convert the route to RegExp using the
// Backbone Router's internal convert
// function (if it already isn't a RegExp)
route = _.isRegExp(route) ? route : Router._routeToRegExp(route);
// Test the regexp against the current fragment
return route.test(fragment);
});
// Returns callback name or false if
// no matches are found
return matched ? matched[1] : false;
} else {
// Just return current hash fragment in History
return Backbone.history.fragment
}
}
});
// Example uses:
// Location: /home
// console.log(Router.current()) // Outputs 'home'
// Location: /user/1
// console.log(Router.current(true)) // Outputs 'user'
// Location: /user/2
// console.log(Router.current()) // Outputs 'user/2'
// Location: /test
// console.log(Router.current(true)) // Outputs 'completelyDifferent'
いくつかの改善ができると確信していますが、これはあなたが始めるための良い方法です。また、Routeオブジェクトを拡張することなく、この機能を簡単に作成できます。これが私のセットアップにとって最も便利な方法だったので、これを行いました。
私はまだこれを完全にテストしていないので、何か南に行くかどうか知らせてください。
関数にいくつかの変更を加えたので、ハッシュまたはルートのコールバック名を返す代わりに、フラグメント、パラメーター、およびルートを含むオブジェクトを返すので、ルートから行うのと同じように、現在のルートからすべてのデータにアクセスできますイベント。
以下の変更を確認できます。
current : function() {
var Router = this,
fragment = Backbone.history.fragment,
routes = _.pairs(Router.routes),
route = null, params = null, matched;
matched = _.find(routes, function(handler) {
route = _.isRegExp(handler[0]) ? handler[0] : Router._routeToRegExp(handler[0]);
return route.test(fragment);
});
if(matched) {
// NEW: Extracts the params using the internal
// function _extractParameters
params = Router._extractParameters(route, fragment);
route = matched[1];
}
return {
route : route,
fragment : fragment,
params : params
};
}
詳細なコメントと説明については、前のコードを参照してください。ほとんど同じように見えます。
_.find
としてthis
、関数の3番目のパラメーター(コンテキストを設定)をとして設定できるため、Router
変数の必要性をなくすことができます(@DanAbramovがこれをすでに行いました)。
Marionette.AppRouter
、上記の関数を使用してルーターを拡張しますが、の代わりに使用Router.appRoutes
しRouter.routes
ます。
ルーターのルート設定を使用する場合は、それを含めて「実際の」フラグメントを取得することもできます。
(Backbone.history.options.root || "") + "/" + Backbone.history.fragment
これは、Simonの回答の少し冗長な(または、好みによっては、より読みやすい)バージョンです。
current: function () {
var fragment = Backbone.history.fragment,
routes = _.pairs(this.routes),
route,
name,
found;
found = _.find(routes, function (namedRoute) {
route = namedRoute[0];
name = namedRoute[1];
if (!_.isRegExp(route)) {
route = this._routeToRegExp(route);
}
return route.test(fragment);
}, this);
if (found) {
return {
name: name,
params: this._extractParameters(route, fragment),
fragment: fragment
};
}
}
のソースをRouter
見ると、ルーターが何かが変更されたことを示すイベントをトリガーすると、「route:name」として名前が渡されることがわかります。
http://documentcloud.github.com/backbone/docs/backbone.html#section-84
いつでもルーターの「ルート」イベントをフックして保存し、現在のルートを取得できます。
route
場合trigger
は イベントを取得できませんtrue
(推奨&デフォルト)。