Використовуючи хребет, чи можна мені назвати поточний маршрут? Я знаю, як прив’язати події до зміни маршруту, але я хотів би мати можливість визначити поточний маршрут в інший час, між змінами.
Використовуючи хребет, чи можна мені назвати поточний маршрут? Я знаю, як прив’язати події до зміни маршруту, але я хотів би мати можливість визначити поточний маршрут в інший час, між змінами.
Відповіді:
Якщо ви застосували маршрутизатор у вашій програмі, наступний рядок повертає поточний фрагмент:
Backbone.history.getFragment();
"[...] Історія служить глобальним маршрутизатором (за кадром), щоб обробляти події хеш-зміни або pushState, відповідати відповідному маршруту та викликати зворотні виклики. Ніколи не потрібно було самостійно створювати один з них - ви повинні використовувати посилання до Backbone.історії, яка буде створена для вас автоматично, якщо ви використовуєте маршрутизатори з маршрутами. [...] "
Якщо вам потрібна назва функції, пов'язаної з цим фрагментом, ви можете зробити щось подібне всередині сфери вашого маршрутизатора:
alert( this.routes[Backbone.history.getFragment()] );
Або так із-за маршрутизатора:
alert( myRouter.routes[Backbone.history.getFragment()] );
Backbone.history.getFragment(), тому що Backbone.history.fragmentце приватне приховане майно.
Відповідь Роберта цікава, але, на жаль, вона спрацює лише в тому випадку, якщо хеш точно такий, як визначено в маршруті. Якщо у вас, наприклад, є маршрут, user(/:uid)він не буде збігатися, якщо Backbone.history.fragmentє "user"або "user/1"( або обидва, що є двома найбільш очевидними випадками використання для такого маршруту). Іншими словами, відповідне ім'я зворотного виклику він знайде лише в тому випадку, якщо хеш точно "user(/:uid)"(дуже малоймовірний).
Так як я потребував в цій функції я продовжив Backbone.Routerз current-функцією , що деякі з багаторазово використовує коду використання об'єкта історії та маршрутизатора відповідно до поточного фрагментом проти певних маршрутів для запуску відповідного зворотного виклику. У випадку мого використання він бере необов’язковий параметр route, який, якщо встановлено щось істинне, поверне відповідну назву функції, визначену для маршруту. Інакше він поверне поточний хеш-фрагмент з Backbone.History.fragment.
Ви можете додати код до наявного розширення, де ви ініціалізуєте та встановите маршрутизатор Backbone.
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, тим самим усуваючи потребу в Routerзмінній (@DanAbramov зробив це вже).
Marionette.AppRouter, розширити маршрутизатор з функцією вище, але заміна Router.appRoutesдля Router.routes.
Щоб отримати маршрут (або URL-адресу) виклику від оброблюваного маршруту, ви можете отримати його, перевіривши
Backbone.history.location.href ... повна URL-адреса Backbone.history.location.search ... рядок запиту, починаючи з?
Я потрапив сюди в пошуках цієї відповіді, тому, мабуть, я повинен залишити те, що знайшов.
Якщо ви використовуєте кореневу настройку для маршрутизатора, ви також можете включити її, щоб отримати "справжній" фрагмент.
(Backbone.history.options.root || "") + "/" + Backbone.history.fragment
Ось трохи більше багатослівним (або, в залежності від вашого смаку, більш зручним для читання) версії відповіді Саймона :
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 (рекомендується та за замовчуванням).