For example I have:
(function (exports, $, _, CategoriesController) {
"use strict"
var App = exports.App;
App.Routers = {},
App.Routers.Index = Backbone.Router.extend({
routes: {
"category=:category": "category",
"*actions" : "defaultRoute"
},
page: function (pageNumber) {
App.CategoriesFilter.setPage(pageNum);
},
defaultRoute: function () {
alert('default');
}
});
}(window, jQuery, _));
But what if page number should be only integer? how to check it in the router? Is it possible? If not, - how to perform other action? Using navigate?
I've found a link that might be what you're looking for:
http://blog.rjzaworski.com/2011/12/regex-routing-with-backbone-js/
Related
I'm trying to pass a URL as a parameter to the backbone router class but it just won't trigger the callback, when passing non-url string, it does trigger it.
var Workspace = Backbone.Router.extend({
routes: {
"myurl/:url": "myurl"
},
myurl: function(url) {
alert('parameter passed: ' + url);
},
});
it works well when linking to
#/myurl/hello-world
but nothing happens when linking to
#/myurl/http://www.somewebsite.com/folder?withparameter=123
Found it. replace :parameter with *parameters so in my case:
routes: {
"myurl/:url": "myurl"
},
should be
routes: {
"myurl/*url": "myurl"
},
I have main app with subapps:
main_app
|-mainRouter.js
|-sub_app
|-subAppRouter.js
subAppRouter.js extends mainRouter.js. subAppRouter.js has handler for route (e.g. /app1/item/). I have no access to subAppRouter.
Here is what I need:
In mainRouter I want to create routing that will handle all URL's from all apps.
It should handle route , make some check and in one case it should continue firing handler from subAppRouter for that url, else it should make redirect (e.g. /app2/somepage).
Could someone helps me with finding the best solution how to do it?
In other words: how to realize interceptor pattern via router in backbone?
Thanks
i will rephrase your question in points
1- you have a main router for common routes
2- you have a specialized router for some app routes
3- you need your main router to choose weather to handle the route of just forward it to sub router
to achieve this i suggest the following
1- create the main router , extending Backbone.Router
var mainRouter = Backbone.Router.extend({
routes:{
'index':'loadIndex',
//other common app routes......
},
loadIndex: function(){
//code to load index
}
});
2- then define the sub router for app,extending the main router, but notice how routes is defined
var subAppRouter = mainRouter.extend({
initialize: function(){
// here we will extend the base routes to not lose default routing, and add app special routing
_.extend(this.routes, {
'subApp/index': 'subAppIndex'
});
},
subAppIndex: function(){
// code to load sub app index
},
});
then you can use the sub router which will contains the base routing also
Here is a good article about subrouting. This works perfect for me.
Include subroute js lib in your project:
<script type="text/javascript" src="backbone.subroute.min.js"></script>
HTML body example:
App1
App2
<div class="app">
</div>
JS Code example:
var MyApp = {};
MyApp.App1 = {
Router: Backbone.SubRoute.extend({
routes: {
"": "init",
"sub1": "sub1"
},
init: function () {
console.log("app1");
$(".app").html($("<h1 />", {text: "App1"}));
$(".app").append($("<a/>", {href: "#app1/sub1", text: "sub1"}));
},
sub1: function () {
console.log("sub1");
$(".app").append($("<h2 />", {text: "sub1"}));
}
})
};
MyApp.Router = Backbone.Router.extend({
initialize: function () {
if(!MyApp.Routers){
MyApp.Routers = {};
}
},
routes: {
"app1/*subroute": "invokeApp1Router",
"app2": "app2"
},
invokeApp1Router: function (subroute) {
if(!MyApp.Routers.App1){
MyApp.Routers.App1 = new MyApp.App1.Router("app1/");
}
},
app2: function () {
console.log("app2");
$(".app").html($("<h1 />", {text: "App2"}));
}
});
$(document).ready(function () {
new MyApp.Router();
Backbone.history.start();
})
Just want to get some basic routing up and going. Having seen a number of examples I thought the code below should work, but when I run I get the error "Unable to get property 'doChat' of undefined or null reference". Do I have the initialization sequence wrong?
require(["marionette", "jquery.bootstrap", "jqueryui"], function (Marionette) {
window.App = new Marionette.Application();
App.start();
App.addRegions({
//add some regions here
});
//Set up routing
var AppRouter = Marionette.AppRouter.extend({
appRoutes: {
"": "doDefault",
"chat": "doChat"
},
doDefault: function () {
alert("doing default...")
},
doChat: function () {
alert("doing chat...")
}
});
var router = new AppRouter();
//History
if (Backbone.history) {
Backbone.history.start();
}
})
The AppRouter allows two types of routes, standard backbone routes as defined in the routes property and routes which call functions in another object defined in the appRoutes property.
So to get you above code working, you can do one of two things. The quickest is simply to change the appRoutes property to routes which will do normal backbone routing. The second option is to create another object and pass that to the AppRouter as the controller during instantiation:
var myController = {
doDefault: function () {
alert("doing default...")
},
doChat: function () {
alert("doing chat...")
}
}
var router = new AppRouter({
controller: myController
});
This is detailed in the AppRouter documentation.
I am using backbone.js routes and i am struggling to make history to work. Here is the code i have:
$(function() {
var AppRouter = Backbone.Router.extend({
routes: {
"/": "initHome",
"home": "initHome",
"projects": "initProjects",
"project/:id" : "initProject"
}
});
// Instantiate the router
var app_router = new AppRouter;
app_router.on('route:initProject', function (id) {
// Note the variable in the route definition being passed in here
getContent("project",id);
});
app_router.on('route:initProjects', function () {
getContent("projects");
});
app_router.on('route:initHome', function () {
getContent("home");
});
// SINGLE PAGE MAGIC
$(document).on("click",".links",function(e) {
var href = $(this).attr("href");
var url = lang + "/" + href;
page = $(this).attr("data-id");
var param = $(this).attr("data-param");
if (typeof(param) == 'undefined') { param = ""; }
if(activepage != href && !main.hasClass("loadingPage")){
loader.show();
firstInit = false;
activepage = href;
res = app_router.navigate(url, true);
getContent(page,param);
}
return false;
});
Backbone.history.start({pushState: true, root: "/karlin/"});
});
Push state is working fine on click, but it wont call getContent() function when i try back/next buttons in the browser. I am an newbie to backbone, so any advice will be helpful.
Change this: res = app_router.navigate(url, true);
To this: app_router.navigate(url, {trigger: true});
I can't see any reason to create a variable "res".
IMHO you've got a convoluted implementation of Backbone. I'd suggest moving your routes to the constructor like so:
var AppRouter = Backbone.Router.extend({
routes: {
"/": "initHome",
"home": "initHome",
"projects": "initProjects",
"project/:id" : "initProject"
},
initProject: function (id) {
// Note the variable in the route definition being passed in here
getContent("project", id);
},
initProjects: function () {
getContent("projects");
},
initHome: function () {
getContent("home");
}
});
// Instantiate the router
var app_router = new AppRouter;
Also, if you set up your routes properly like in the Backbone docs,
routes: {
"help": "help", // #help
"search/:query": "search", // #search/kiwis
"search/:query/p:page": "search" // #search/kiwis/p7
},
you can pass parameters to the routes with traditional links. You can also move your if activePage statement to the router as a helper function for changing pages.
Router.navigate is for rare instances.
I suggest, reading the Backbone docs over and over. I learn something new every time. There's a lot there and Backbone is doing things efficiently already. No need to reinvent the wheel.
Hope this helps!
I second Andrew's answer: your use of routing is a bit odd.
If you're interested in learning more about why, as Andrew says, "Router.navigate is for rare instances", read pages 32-46 here: http://samples.leanpub.com/marionette-gentle-introduction-sample.pdf
It's part of the sample for my book on Backbone.Marionette.js, but routing concepts remain the same. In particular, you'll learn why the default trigger value is false, and why designing your app routing with that in mind will make your apps better.
I have the following router defined, but the .route function doesn't seem to be setting. What am I doing wrong? Thanks, in advance, for the help.
# app.js.coffee
initialize: =>
router = new Backbone.Router
router.route "foo/:bar", "baz"
console.log router.routes # returns undefined
The routes you create using Router.route are stored internally in the History object -- they're not added to the Router.routes collection.
They still work though, see here for proof. Note that in this.routes, only the home route is defined, but you're still able to hit the baz route. You can see the baz route if you check Backbone.history.handlers, which is where the routes are actually stored.
var Router = Backbone.Router.extend({
initialize: function() {
this.route("foo/:bar", "baz");
},
routes: {
"": "home"
},
home: function() {
console.log("home hit");
},
baz: function(bar) {
console.log('test hit: ' + bar);
},
});
var router = new Router();
console.log(this.routes);
console.log(Backbone.history.handlers);
Backbone.history.start();
router.navigate("foo/testbar", { trigger: true });
Note though, I think you need to use this in your code, because router won't be defined yet inside initialize:
#route "foo/:bar", "baz"