Backbonejs and defaultRoute - javascript

I start to learn how to use backbonejs for a web app and I've got a little problem with the defaultRoute when the app is launch.
Here is my script
var AppRouter = Backbone.Router.extend({
routes: {
"user/:id": "getUser",
"*actions": "defaultRoute"
}
});
var app_router = new AppRouter;
app_router.on('route:defaultRoute', function() {
$("#content").load("pages/page1.html");
});
app_router.on('route:getUser', function(id) {
$("#content").load("pages/user.php?id="+id);
});
Backbone.history.start();
When you go on the App like http://www.myapp.com the defaultRoute is not loaded.
When I click a link not referenced in the routes, page1.html is loaded.
My question is: How can I set the defaultRoute when I go on the app ?
Thank you

Your code demonstrates a somewhat unusual use of backboneJS, as you're loading complete HTML or pages into a the div container, instead of using backbone views and underscore templates.
Regardless, you may want to consider the following implementation, instead of using the app_router.on(...) syntax.
Consider the following implementation:
var AppRouter = Backbone.Router.extend({
routes: {
"":"defaultRoute" //The router will default to this route if no other routes are matched ("")
"user/:id": "getUser",
...more routes
},
defaultRoute:function(){
...default route functionality
},
getUser:function(id){
...
}
});

Related

How to manually navigate to route with React + React-Router-Component

I've created a React component library, which JS react page views render and control.
// Application js, controls the routes.
var Application = React.createClass({
mixins: [Router],
routes: {
'/': HomePage,
'/users': PerformerPage
// , null: NotFoundPage
},
render: function () {
return this.transferPropsTo(this.renderRouteHandler());
}
});
// and in HomeView.js, a link to a page
<Link href={'/users'}>{'Test'}</Link>
This all works wondefully. Except when i manually navigate to that link, it clearly doesn't handle it yet... so my question is, if the server redirects to the index ALWAYS, will react catch this? I'm pretty well versed in grunt, and build automation in general, but node js servers aren't my forte yet unfortunately.
In my grunt server
task =>
'connect:livereload',
'webpack:development',
'open',
'watch'
Final result: User should paste address into bar (ie site.com/users) and be navigated to the applications /users.
Thanks :D Any help would be great.
One way to do it is to put the routes in their own file (say client/routes.js)
module.exports = {
'/': HomePage,
'/users': PerformerPage
// , null: NotFoundPage
};
Now you can require them in your Application file, and in your node server:
var app = require('express')();
var routes = Object.keys(require('../client/routes'));
routes.forEach(function(route){
app.get(route, function(req, res){
res.sendFile(__dirname + '/static/index.html');
});
});

EmberJS URL format

In EmberJS you can build a URL route as?:
http://www.mydomain.com/section/detail-123.html
123 is a variable
in angularJS the separators in URLs must be slash, I think also in Ember
Is there a framework of this kind that can do this kind of URLs?
In ember one can achieve this kind of urls by combining the possibilities provided by the serialize hook of Route class (http://emberjs.com/api/classes/Ember.Route.html#method_serialize) to modify the url as required and Ember.Location (http://emberjs.com/api/classes/Ember.Location.html) to remove the hash tag and enable only slashes in the url.
Example,
http://emberjs.jsbin.com/jenabegi/1/
http://emberjs.jsbin.com/jenabegi/1/edit
App = Ember.Application.create();
App.Router.map(function() {
/*the /jenabegi/1 part is added to make it function in jsbin*/
this.route('index', {path: '/jenabegi/1/' });
this.route("detail",{path:"/jenabegi/1/section/:detail_id"});
});
App.Router.reopen({
location: 'history'
});
App.IndexRoute = Ember.Route.extend({
redirect:function(){this.transitionTo("detail",{value:"123"});}
});
App.DetailRoute = Ember.Route.extend({
serialize:function(model,params){
return {"detail_id":"detail-"+model.value+".html"};
}
});

EmberJS: Change path to access a route

I have a Router.map defined to my application. I'm working with EmberJS AppKit architecture. https://github.com/stefanpenner/ember-app-kit
I'd like to access to my page "profile" using the following path:
http://localhost:8000/#/profile
But, the name of my route differ to this path, because it's call user-profile, so I did this:
router.js
var Router = Ember.Router.extend();
Router.map(function () {
this.resource('user-profile', { path: 'profile'}, function() {
//Some other things...
});
});
export default Router;
user-profile.js
export default Ember.Route.extend({
model: function () {
return this.store.find('user-profile');
}
});
When I launch my application, Ember is telling me that profile route doesn't exist, even though I defined the path:
Uncaught Error: Assertion Failed: Error: Assertion Failed: The URL '/profile' did not match any routes in your application
Do you know what's wrong with my code at this point?
Thanks
I dont use ember appkit but perhaps try with underscore, ie 'user_profile' and rename your file too. Just a shot in the dark.
I would have to guess it is the way that you are designing your router and the namespace.
Typically a barebones Ember app requires:
window.App = Ember.Application.create({
LOG_TRANSITIONS: true,
LOG_TRANSITIONS_INTERNAL: true
});
App.Router.map(function () {
this.resource('user-profile', { path: 'profile'}, function() {
//Some other things...
});
In your example your router is not in the App namespace, or whatever your root object is named (It doesn't have to be 'App'). I would give this a try or maybe post more code if there are other factors I do not see here.
Also, typically you would name your route userProfile. While i dont think the dasherized name is a problem, it doesn't follow Ember naming conventions.
Hope this helps.

Marionette Application with Multiple Entry Points

Currently the application that I am building is a single page marionette application with a single entry point. When the user is at "/" I pass a very simple jade document:
body
header
section
div#main
script(src='/javascripts/lib/require.js', data-main='/javascripts/application.js')
The only javascript that I am loading to this is my require.js page, and once that's loaded I start things with Backbone.Marionette.Application() and thats the only app object I create for the whole app and that takes care of everything.
define([
'zepto', 'marionette', 'router', 'events'],
function ($, Marionette, router, Event) {
// set up the app instance
var MyApp = new Backbone.Marionette.Application();
MyApp.addRegions({
main: "#main"
});
MyApp.addInitializer(function(){
});
MyApp.on("initialize:after", function(){
var newRouter = new router(MyApp);
Backbone.history.start();
});
MyApp.start();
return MyApp;
});
If I have multiple entry points (in other words, multiple html pages created in the server side) for example one for "Classroom", one for "User Profile" one for "Discussion" , does that mean I need separate require.js documents to load for each page and separate Backbone.Marionette.Application() objects?
You don't have to otherwise it's too troublesome :) That's the job of Route.
At first, don't start app right away in the app definition. Remove this line
MyApp.start();
Then, put such command at the footer of your html page, and better after dom ready
$(function(){
MyApp.start();
});
The third is the most important. You need to define your routes in App or sub app(better). Here is the code "borrowed" from BBCloneMail
BBCloneMail.module("ContactApp", {
startWithParent: false,
define: function (ContactApp, App, Backbone, Marionette, $, _) {
var Router = Marionette.AppRouter.extend({
before: function() {
App.startSubApp("ContactApp", {});
},
appRoutes: {
"contacts": "showContacts"
}
});
In above case, when visitor enters your app from example.com/contacts, the method showContacts will be trigger and that's the start of your arranging page specific logic.
For more about appRouter:
https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.approuter.md

Access App.method from within App.router.method

I'm building a backbone.js + require.js application and I have run into the following issue.To structure my application I have an App.js file which as the following contents:
define(function(require) {
'use strict';
var _ = require('underscore'),
Backbone = require('backbone'),
Router = require('router'),
ModuleManager= require('moduleManager');
var App = function App() {
var base = {
router: new Router(),
moduleManager: new ModuleManager(),
start: function start(){
Backbone.history.start({pushState: true});
this.router.navigate('home', {trigger: true});
}
};
return _.extend(
base,
Backbone.events
);
};
return App;
});
The application is started with window.myApp = new App();, then myApp.start();.
The contents of router.js are as follows :
define(function(require) {
'use strict';
var _ = require('underscore'),
Backbone = require('backbone');
var Router = Backbone.Router.extend({
routes: {'home': 'home'},
home: function home() {
// MY ISSUE IS HERE
App.moduleManager.add('moduleName');
}
});
return Router;
});
The moduleManager is a utility function/object for :
Adding application modules via App.moduleManager.add('module') by requiring require.js files (backbone views + collections),
Doing some checks (e.g. ensuring the module doesn't already exist),
Centrally storing modules in App.moduleManager.modules
Everything is working fine except for the following point :
How can I call App.moduleManager from within App.router.home or any other route (App.router.xyz) ?
Within App.router.home, this can't refer to App (?)
Within router.js, I can't call App = require('app') because I would be making a circular dependency between App.js and Router.js
I'm not sure if I have a global application structure problem or if there is just a simple language construct which can work around this problem. Thanks for any help you can provide.
You could pass the object you need in the router's constructor.
But I would suggest using events. In the route, trigger an event, then listen for that event in the app. This leaves the router to do a single job, responding to route changes from the browser (back/forward clicks).
In router:
home: function() {
Backbone.trigger('home:show');
}
In app:
start: function(){
Backbone.history.start({pushState: true});
Backbone.on('home:show', this.showHome, this);
},
showHome: function(){
this.router.navigate('home', {trigger: false}); // just update, dont trigger route
this.moduleManager.add('moduleName');
}
Now if you want to change what the app is showing from your code, you can just trigger this event, instead of calling navigate on the router.
Some other code, maybe a menu view:
homeClicked: function(){
Backbone.trigger('home:show');
}
This would show your home view, and also update the history.

Categories

Resources