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.
Related
I'm trying to do something seemingly simple. I have the following defined:
#Routes([
{ path: '/stores', component: StoresComponent },
{ path: '/stores/new', component: StoresCreateComponent}
])
When I navigate to /stores I display a list of existing stores. I have a link on that page to navigate to a screen to create a new store. However, when I navigate to /stores/new, I get the following:
browser_adapter.ts:78Error: Uncaught (in promise): Component 'StoresComponent' does not have route configuration
I'm pretty new to Angular so I'm not entirely sure what I need to do in order to get a route like that working.
Order routes so that more specific ones come first and less specific ones last. That's a current limitation of the RC.1 router.
#Routes([
{ path: '/stores/new', component: StoresCreateComponent}
{ path: '/stores', component: StoresComponent },
])
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>
My app basically takes some form input and returns a set of results. I have two routes
routes: {
'': 'search',
'search': 'search',
'results/:query': 'results'
},
results: function(query) {
var search = new ResultsSearchView();
var grid = new GridView({ query: query });
}
If the query contains any characters / specifically (can totally happen in this case), they are added to the URL and my route breaks.
I have tried using encodeURI() and encodeURIComponent() bit I'm not having any luck. How are you folks handling such things?
You can use encodeURIComponent when building the URL to convert the / to %2F and then decodeURIComponent inside the route handler to convert them back; the HTML would end looking like this:
no slash
with slashes
and then in the router:
routes: {
'results/:query': 'results'
},
results: function(query) {
query = decodeURIComponent(query);
// Do useful things here...
}
Demo: http://jsfiddle.net/ambiguous/sbpfD/
Alternatively, you could use a splat route:
Routes can contain parameter parts, :param, which match a single URL component between slashes; and splat parts *splat, which can match any number of URL components.
So your HTML would be like this:
no slash
with slashes
and your router:
routes: {
'results/*query': 'results'
},
results: function(query) {
// Do useful things here...
}
Demo: http://jsfiddle.net/ambiguous/awJxG/
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
Here is my application-router.js file where i'm creating Backbone.Router object with just only few routes:
var App = App || {};
App.Router = Backbone.Router.extend({
routes : {
'' : 'showDashboard', // Not shown
'*other': 'showModalError'
},
defaultRoute : function(other) { $('#modal404').modal(); }
});
In main javascript file application.js i'd like to programmatically add routes. I've tried with route() function and it doesn't work, routes are not added. It works however passing an object to the "constructor", but that will override already defined routes:
// This works and overrides all defined routes in App.Router
var router = new App.Router({ routes : { '/test/me' : 'testRoute' } });
// This is not working
router.route(ExposeTranslation.get('customers.new.route'), 'newCustomer');
router.route('/test/me/again', 'testAgainRoute');
In fact console.log(App.Router) shows:
routes Object { /test/me="testRoute"}
I suppose i'm missing something i can't figure out, i'm beginning learning this little piece of powerful javascript.
Your router.route calls are working, those calls aren't your problem. When you call route to add a new route, the new route goes at the end of the routing list. In particular, the routes that are added by your route calls go after '*other' and '*other' will match anything so your new routes will be effectively ignored.
Try removing your '*other' route from routes and adding it after your two route() calls:
routes : {
'' : 'showDashboard' // Not shown
},
router.route(ExposeTranslation.get('customers.new.route'), 'newCustomer');
router.route('/test/me/again', 'testAgainRoute');
router.route('*other', 'showModalError');
The routes aren't stored in App.Router object, they're stored inside Backbone.history:
route: function(route, name, callback) {
// ...
Backbone.history.route(route, _.bind(function(fragment) {
//...
}, this));
return this;
},
That's why your console.log(App.Router) doesn't say anything helpful.