I have a Backbone Router:
class X.Routers.Main extends Backbone.Router
routes:
'/': 'home'
'pageb': 'actionb'
'pagec': 'actionc'
Pages B and C work, but navigating to http://domain.ext/ results in a page reload instead of triggering the right route.
How can I prevent this?
You can either set "*path": "home" as your last route which will make it a default route or set "" (instead of "/")as your first route (which means root directory)
your base url path IS NOT "/", BUT "" (empty string)
I usually add optional "/" at the end of each route configuration, just in case
I also usually add default action handler at the end of configuration
So my routes configuration would be like:
routes = {
'': 'home',
'pageb(/)': 'actionB', // so /pageb or /pageb/ will call the same function
'pagec(/)': 'actionC', // so /pagec or /pagec/ will call the same function
'*action': 'defaultAction' // you can use it to render 404, or call home function
}
Hope this help
Related
I have an angular 2 app with the following routes:
#RouteConfig([
new Route({ path: '/', component: Home, name: 'Home', useAsDefault: true}),
new Route({ path: '/employees', component: ViewEmployees, name: 'ViewEmployees'}),
new Route({ path: '/employees/add', component: AddEmployee, name: 'AddEmployee'}),
])
among others. When I change routes in the following way:
<a [routerLink]="['ViewEmployees']">View Employees</a>
There are no issues. I can change routes in this way from either the home page or the AddEmployee route. The issue comes when I'm in the AddEmployee route and try to change routes in a programmatic way like this:
import {Router} from 'angular2/router';
...
constructor(private _router:Router) {}
...
navigate() {
this._router.navigate(['ViewEmployees']);
}
it doesn't work. It sends me to the ViewEmployees view and then reloads the entire app. If I do that same programmatic route change from the Home component I don't have any issues; the app doesn't reload.
Does anyone have any ideas why it would do this in just this one case? I need it to work so that I can save the employee that's added and then go back to the employee list view.
Thanks in advance for the help!
Do you call navigate() from within a <form> Tag?
I had the same Problem. There exist some issues describing this behavior on Angular2s GitHub but they are all closed because they belong to the old router. The page reload seems to occur when you use router.navigate() inside a function called by a submit button inside a form. This can cause the browser to append a ? at the end of the URL and reload it.
The solution is very simple: Just return false at the end of your navigate() function. This prevents the bowser to use it's default action when submitting forms. Usually angular stops such default behavior but strangely not in this case.
Have you set the <base href>?
As mentioned in the Router guide
Add the following code to your index.html after the opening head tag:
<base href="/">
From RouterLink docs:
The first route name should be prepended with /, ./, or ../. If the route begins with /, the router will look up the route from the root of the app. If the route begins with ./, the router will instead look in the current component's children for the route. And if the route begins with ../, the router will look at the current component's parent.
Use:
<a [routerLink]="['/ViewEmployees']">View Employees</a>
Is there a built in call to find out the current page, in a bootstrap environment.. I am trying to hide some of the links depending on the page i am on.
we have a router as follows;
var AppRouter = Backbone.Router.extend({
routes : {
// Define some URL routes
'login' : 'showLogin',
'main' : 'showMain',
'faq' : 'showFaq
}
If you're looking for the last route triggered in the router then you can access it using
Backbone.history.fragment
Provided history was started after initializing routers.
I have the following routes object:
routes: {
"*defaults": "home",
'#test': 'test'
}
Here's the url options:
myApp.html // home is called as desired
myApp.html#test // home is called instead of test
What did I miss?
Per the docs, you don't need the hash mark in the route (that's implied by the Backbone routing convention). Also, the "*defaults" route is going to catch everything, so you should put it last after more specific routes. So, like this:
routes: {
'test': 'test'
"*defaults": "home",
}
Should result in myApp.html#test getting routed to test.
I must be losing it. I've set up the simplest Backbone app, but can't seem to get routes to respond. Here's my router (in coffeescript):
class BackboneSupport.Routers.TicketsRouter extends Backbone.Router
initialize: ->
#tickets = new BackboneSupport.Collections.TicketsCollection()
routes:
"/new" : "newTicket"
".*" : "index"
newTicket: ->
alert 'hi, from the new ticket route'
index: ->
// just to prove a point
$('#tickets').html('tickets go here')
#navigate('/new')
And I get the whole train moving with:
<div id="tickets"></div>
<script type="text/javascript">
$(function() {
window.router = new BackboneSupport.Routers.TicketsRouter();
Backbone.history.start();
});
</script>
As you would expect, the root route (index) populates #tickets with placeholder text and successfully navigates to the /new route (confirmed via the address bar), however, it does not alert anything, meaning the newTicket method is not being triggered.
What am I missing here?
UPDATE:
Per rjz below, I updated the navigate method to:
#navigate('/new', {trigger: true})
But strangely, still no alert :/
You shouldn't have the leading slash in your route, you want this:
class BackboneSupport.Routers.TicketsRouter extends Backbone.Router
routes:
"new": "newTicket"
".*" : "index"
#...
Demo: http://jsfiddle.net/ambiguous/veSDF/1/
From the fine manual:
extend Backbone.Router.extend(properties, [classProperties])
[...] Note that you'll want to avoid using a leading slash in your route definitions:
Is there a general event that fires every time we navigate to a different URL?
window.App =
Models: {}
Collections: {}
Views: {}
Routers: {}
init: ->
# Initialize Routers
new App.Routers.Main()
# Initialize History
Backbone.history.start(pushState: true)
# BIND VIEW CHANGE?
$(#).on 'changeOfRoute', ->
console.log "Different Page"
$(document).ready ->
App.init()
Doing this per view is possible, but I'm looking for a general solution.
There is the "route" event on the Router:
http://backbonejs.org/#Events-catalog
"route" (router, route, params) — Fired by history (or router) when any route has been matched.
This allows you to bind to specific routes.
If you want to fire a handler after any route, bind to "route", and the route will be the first argument:
myRouter.on("route", function(route, params) {
console.log("Different Page: " + route);
});
This will only trigger events for your explicitly defined routes. If you want to trigger events for routes that are not explicitly defined, then add a 'splat' route as per How to detect invalid route and trigger function in Backbone.Controller
From the Backbone docs
This method is called internally within the router, whenever a route matches and its corresponding callback is about to be executed. Override it to perform custom parsing or wrapping of your routes, for example, to parse query strings before handing them to your route callback, like so:
var Router = Backbone.Router.extend({
execute: function(callback, args) {
args.push(parseQueryString(args.pop()));
if (callback) callback.apply(this, args);
}
});
This site has some useful code for redefining the Router to support 'before' and 'after' hooks, though it would require updating with each version-change of Backbone.
#TTT: Unfortunately Backbone doesn't give us a before/after event, so you will need to overwrite or extend the Router.route. You can find the way to do that in this answer: https://stackoverflow.com/a/16298966/2330244
May be this extension would be useful for you:
https://github.com/zelibobla/Backbone.RewindableRoute/blob/master/backbone.rewindableRoute.js