I'd appreciate any insight into whether this is a "correct" way of doing things and also what's causing the error I'm seeing.
I have added backbone to my base meteor install meteor add backbone
Then I set up a router.js file as follows (just showing 2 pages as example);
var Router = Backbone.Router.extend({
routes: {
"": "index",
"help": "help",
...
},
index: function() {
Session.set('currentPage', 'homePage');
},
login: function() {
Session.set('currentPage', 'loginPage');
},
...
Then for the pages I have html files with templates looking something like this...
<template name="homepage">
{{#if route}}
You're at the Home Page!
{{/if}}
</template>
Then for the main page I have an html file that contains the following;
<body>
...
{{> homepage}}
{{> loginpage}}
{{> helppage}}
...
</body>
This works for all of the pages except the one designated 'homepage', this template is always rendered regardless of where I am on the site. e.g. myapp/ as the root page just displays the homepage template, but myapp/loginpage displays the loginpage template and the homepage template. So every single page displays the contest of the homepage template.
Any insight? (or better ways to structure).
Thank you
Finally a question that I can answer because it's what I've been doing 60 hours a week at work for the last few months :-P
You're doing a few things wrong here, and they're extremely simple fixes that will get you fired up in no time.
First thing
You need to instantiate all of your routers and then initialize Backbone.pushState().
// This is just how I have been doing it, there are many correct ways.
var LoadedRouters = {
Module1 : new Module1Router(),
Module2 : new Module2Router(),
...
};
// After all routes instantiated, we tell Backbone to start listening.
Backbone.history.start({ pushState : true, root : "/" });
It's very important that you set the root property correctly, or else weird things start happening.
Second thing
You HAVE TO list your routers from the most-specific to the least-specific, top-down. The URL structure you outlined above will ALWAYS match the first route and trigger it.
routes : {
"help/phones/newservice" : HandleNewServiceHelp(),
"help/phones/oldservice" : HandleOldServiceHelp(),
"help/phones(/:any)" : HandleAllPhoneHelp(),
"help(/:any)" : HandleAllHelp(),
"" : HandleAllUnmatchedRoutes()
};
Backbone.router can be a tricky thing to learn.
Related
In my Angular 2 app (RC4), when the index.html opens,
I get the error Error: Cannot match any routes: ''
I know this has been asked before, but none of the answers in those cases seems to apply to me; that is, I"m already doing everything recommended to fix this.
I have
<base href="/">
in my head element (also tried
<base href=".">
which makes no difference at all).
I have the following in my app.route.ts:
export const routes: RouterConfig = [
{ path: '', redirectTo: '/instruction-steps', pathMatch: 'full'},
{ path: 'settings', component: SettingsComponent },
{ path: 'find-and-replace', component: FindAndReplaceComponent },
{ path: 'instruction-steps', component: InstructionStepsComponent }
];
The page does render correctly, and my routes to the other views work. If I reload the page, however, I'll not only get the error, but the page does not render.
This is running on lite-server, not ASP.NET.
i can not comment due to low reputation points but are you using angular 2 with asp.net then you have to add code in startup.cs that point to use index.html when no route found.
Here are a few tips to watch out for:
Be sure that modules are properly defined as #NgModule.
Be sure that routing modules are properly added to imports for the module.
Be sure that paths are spelled correctly (e.g. "item" vs. "items")
Be sure that each module is added to the main App Module.
Please note that this is as of the Final release of Angular 2.
I'm using Datatables with AngularJS and the FixedHeader plugin which works fine when the table is displayed on the page. My issue is that when I navigate to a different page (single page application) using angular UI router, the FixedHeader header still shows.
Does anybody know why this is the case?
It looks like that is an issue with the FixedHeader plugin to DataTables.
There is an angular-DataTables module at https://l-lin.github.io/angular-datatables/#/welcome, which has a page about the plugins that work with it. This page lists the FixedHeader plugin and mentions the same issue you are seeing.
See https://l-lin.github.io/angular-datatables/#/withFixedHeader.
This page says the following:
Beware when using routers. It seems that the header and footer stay in
your DOM even when you change your application state. So you will need
to tweak your code to remove them when exiting the state.
It also shows a workaround for angular-ui-router:
$stateProvider.state("contacts", {
templateUrl: 'somewhereInDaSpace',
controller: function($scope, title){
// Do your stuff
},
onEnter: function(title){
// Do your stuff
},
onExit: function(){
// Remove the DataTables FixedHeader plugin's headers and footers
var fixedHeaderEle = document.getElementsByClassName('fixedHeader');
angular.element(fixedHeaderEle).remove();
var fixedFooterEle = document.getElementsByClassName('fixedFooter');
angular.element(fixedFooterEle).remove();
}
});
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>
I am using Hot Towel AngularJs SPA that John Papa created. I wanted to know how can I change the current menu to have sub menus.
[Edited]
The base implementation of HotTowel menu is looping into all routes and show it on the side bar. What I wanted to do is if there are sub-menu for one of the routes then it's content will be grouped in one menu item. similar to dropdowns sub menu
Don't forget that you're working with Models, and Controllers.
The Angular model and controller work in concert with the View John built.
public class HotTowelController : Controller
{
//
// GET: /HotTowel/
public ActionResult Index()
{
return View();
Notice that the Index is the View.
Ok.
look at the url when you run the page.
name
notice that its not loading another page.
That's because it's a SPA framework.
The Index has a Javascript method where we are defining the roles outside of the .NET Framework / MVC
So, we have a modeljs and a controllerjs. Just like MVC we have to use all three. But use those in the APP folder.
The APP Folder
Admin
Common
dashboard
layout
services
viewmodels
views
etc...
So
Go to the Layout Folder
open topnav.html
THen read the viewmodels
shelljs
var routes = [
{ route: '', moduleId: 'home', title: 'Reserve a Seat', nav: 1 },
{ route: 'details', moduleId: 'details', title: 'Poker Details', nav: 2 }];
return router.makeRelative({ moduleId: 'viewmodels' }) // router will look here for viewmodels by convention
.map(routes) // Map the routes
.buildNavigationModel() // Finds all nav routes and readies them
.activate(); // Activate the router
}
Seee what's happening here. We are mapping, knockout and angular have very easy mappings.
http://knockoutjs.com/documentation/plugins-mapping.html
This is an easy way to learn, and the vm is the smae for both only angular your using npm with a much more defined library in open source. both are mit so can't go wrong there.
then look at the config config.route mainjs
What do you see: Are you getting it?
Need more?
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: