How the Backbone Marionette JS router works - backbone.js

I am new to Backbone Marionette JS and wondering how its routing works. Is any one can explain me or point me to the right direction to look at it.
Thanks in advance.

You should have a look at
https://github.com/marionettejs/backbone.marionette/blob/master/docs/marionette.approuter.md
And other Marionette Samples
https://github.com/davidsulc/marionette-gentle-introduction
This is a great place to start with. You will get to know how things work in Marionette and how different is it with Backbone Code Style.

Marionette Router extends the Backbone Router object. It is an object that registers URL's to methods (functions). It means that whenever you navigate to a new URL your client will do a GET request to the server (which will download the html files and css, js imported inside). Then, the method corresponding to the route will be evaluated.
There is a standard used for browsers. Whatever in front of the # is requested to the server, and whatever is after will go inside your Routers.
You only need to instantiate a Router in order for the routes to work. I think it registers to a global variable in Backbone. After you activate the history in Backbone, you can use those routes.

I was looking for something like this, hope this will help someone else. The example is used from Davis Sulc's book Gentle Introduction to Marionette.
ContactManager.module("ContactsApp",function(ContactsApp,ContactManager,Backbone,Marionette_){
ContactsApp.Router = Marionette.AppRouter.extend({
appRoutes: {
"contacts": "listContacts"
});
varAPI={
listContacts: function(){
console.log("route to list contacts was triggered");
}
};
ContactManager.addInitializer(function(){ new ContactsApp.Router({
controller: API
});
});
});

Davis Sulc's book Gentle Introduction to Marionette is a good starting place. Understanding the concept of Marionette.Controller and Marionette.Module will help in splitting up routers for better maintainability.

Related

Upgrade to Angular 2.0 Routing strategy

I am migrating my app from Angular 1.X to Angular 2.0 and I am having thoughts about routing solution while / after migration process.
I am currently using ui-router, with resolve in order to pass data for each route.
After some reading I came across this post. As far as I understand, there is no resolve in the new router. I now have two choices:
Continue using my current ui-router with my hybrid ng1-2 app (is it possible?), and bring each route's data via router's resolve. Will it work?
Change routing and use the new Component Router. This will make the step-by-step upgrade harder, because I will have to change my current Angular 1.X data fetching to be inside each controller / directive + I won't have Angular 2's #CanActivate which will wait for data to be resolved.
Which option is better? Is there another option? What will work here?
Thanks!
I encountered the same issue at work. I tried many things, but in the end I used a service:
var data = {
'foo': 'bar'
}
export const StateData = {
data: data
};
So now at the top of my component I can import the service:
import { StateData } from '/services/StateService.ts';
Then I can set and get data from the service by simply doing:
StateData.data.foo = "something other than bar"
Now when you switch routes, you can retrieve the new updated data within the constructor() or afterViewInit() methods.
*An added bonus of using the StateService is that you can bind your data between all components by simply adding the following method (you can name it whatever):
getStateData(key) {
return StateData.data[key];
}
You can call this method from the dom itself by doing the following:
{{getStateData('foo')}} --> will print out the value "bar"
Now if you change the value of foo within the service in a different component, it will change in the dom, since getStateData() is called whenever a change occurs and the service only loads once on page load.
I believe the init and afterViewInit methods are the reason as to why they have not added resolve to the new router, or maybe they still haven't released the version with it yet.
I hope this helps you out. I do not think using Angular 1.x + Angular 2.0 would be easy, nor would it be fun lol
I recently rebuilt my personal site in angular 2.0. The code is public, so you can check it out. If you look at contactCard.ts, contact-card.html and StateService.ts you can see it in action. Here is the repo:
https://github.com/YashYash/portfolio

How to cache state (page) during history back in Angular JS like IONIC

IONIC has a very good feature to "cache" the state by using ion-nav-view, when user access the state in history, it will not reload the page -- Controller won't be called, and we could enable the cache globally or by page.
While working on a web site, I tend to use Angular JS directly instead of IONIC since IONIC is mainly for the mobile hybrid APP development. However, I really like the way IONIC handle the "history" and page reload. I know that we could leverage Angular Service to keep page data and achieve the similar function. But I feel it's not convenient to code and we have to put everything into service instead of controller.
Take an example here, we have a pagination search on Page A, by clicking each item to navigate to page B for the detailed item information, if we go back to Page A, we do not want to re-execute the pagination search again. I feel this is a very common requirement for most web site, IONIC's ion-nav-view could achieve this function easily without moving data to service, I wonder is there any angular JS plugins or directive which could help to achieve this function, it's something very similar as what IONIC's ion-nav-view does?
I am looking for the answer too, no lucky.
One answer is
http://www.tivix.com/blog/dont-forget-the-back-button-in-your-single-page-ap
the author mentioned ngRouter's [reloadOnSearch] option, but i doubt this answer.
From ui-router v0.2.5, there's reloadOnSearch option too, but it's not for our purpose.
another answer is
http://www.bennadel.com/blog/2801-revisiting-routing-nested-views-and-caching-with-ngroute-in-angularjs-1-x.htm
I think there's no simple way now, you have to keep controller's status, and restore controller's status on popstate event, and reproduce all controller's actions.
The other way is cache rendered-html, but how can angular touch the restored-html still?
you can use $window.history.back()
History is a consequence of navigation. So I think you are actually asking about AngularJS routing which is responsible for navigation and history management features. Angularjs has built-in router but ui-router seems to be more main stream because of its additional capabilities.
I also need the same feature and I found this lib:
http://christopherthielen.github.io/ui-router-extras/#/sticky
I think It can solve the problem but it make a problem on performance
because every opened state still working in background and use memory and cpu. (as I think)
Edit
ui-router added stiky feature please see this link:
ui-router/sticky-states
Here how you can use it
1) Add Plugin
import {StickyStatesPlugin} from "ui-router-sticky-states";
angular.module('myapp', ['ui.router']).config(function($uiRouterProvider) {
$uiRouterProvider.plugin(StickyStatesPlugin);
});
2) Mark a state as sticky
let adminModule = {
name: 'admin',
sticky: true,
views: {
admin: { component: AdminComponent }
}
}

Famous (aka Famo.us) with Backbone router?

Anyone know how to use Famou.us with a router, i.e. Backbone? They have a slick looking Twitter clone, but it doesn't update the URL in web browser. Looking for a decent router option for Famous. See the Twitter clone here:
http://demo.famo.us/tweetus
Famo.us works really well with backbone. It pretty much replaces the View component, and the rest of backbone still functions.
Actually, it also makes the meat of marionette irrelevant too. (although i love the module and event stuff in it)
This document I found explains how they integrate:
https://gist.github.com/AdrianRossouw/d85ce9897c123c42b162

Using Backbone.js Router with No Hash

I am building a multi-page application and would like to leverage Backbone's Router to initialize my views on page load. I haven't been able to find a way to leverage routers without using hashes and I don't need or want to use push state.
Basically, all I want to be able to do is use the Routers URL pattern matching to match the url and initialize my views depending on which page is loaded from the server.
Perhaps I am thinking about this all wrong or maybe there is a way to do this natively in Backbone Routers that I am missing. Any suggestions are greatly appreciated.
From the Backbone documentation (emphasis mine):
Backbone.Router provides methods for routing client-side pages, and connecting them to actions and events.
In other words, the Backbone Router was only designed to handle client-side URLS (the part after the hash), not server-side ones (the part before the hash). There might be a way to hack the Router and Backbone.History to use full URLs instead of just the hash, but it would not be easy and I'd recommend against it.
One alternative you could consider is some sort of onDocumentReady logic that checks the URL of the page and, if it's hash doesn't match it's URL, adds a hash. This would make it so that if someone visits "/foo" your code would convert it to "/foo#foo", and the Backbone Router could be used normally.
Another option though would just be to write your own "router" of sorts, which will actually be simpler than Backbone's because it only needs to work once per page load. Here's a simple example:
var mockRouter = {
foo: function() {
// do stuff for page "foo"
},
bar: ...
}
$(function() {
mockRouter[window.location.pathname]();
});

Backbonejs - Best Approach to making one page web sites/apps

To start off this might not be the right approach and I'm open to other suggestions but please hear me out......
I'm quite new to Backbone JS and was wondering if its possible to use this to build a portfolio/cv site where content would be loaded via AJAX to a container.
To start off simply, i was thinking along the lines of converting my online CV to be more dynamic where sections such as Profile ,Key Technical Skills, Experience and Career History
can someone please offer a few pointers as what the best approach would be?
Would every view need to have a model?
Given the small amount of content, relatively static nature of the data in a CV, and simplicity of what you would need to accomplish, I'm not sure I would recommend using Backbone for this project. It seems that some simple jQuery click event handlers and transition animations would be sufficient to do what you're looking for.
If you're intent on using Backbone is purely for education and learning how to use it, then I would suggest looking for a project that has a more dynamic nature to it's data, with more content to be manipulated.
FWIW, though, you could use Backbone views to help organize your jQuery code for your CV. However, you'll end up writing more code to do this than if you just used jQuery.
For example, if you wanted to show / hide a section when someone clicks on it... here it is in jQuery:
$(function(){
$(".cv-section").click(function(e){
$(e.currentTarget).toggle("fast");
})
});
and here is the same code in Backbone (which uses jQuery for it's DOM manipulation):
CVView = Backbone.View.extend({
events: {
"click .cv-section": "showHide"
},
showHide: function(e){
$(e.currentTarget).toggle("fast");
}
});
$(function(){
var el = $("#cv");
new CVView({
el: el
});
});
These two examples are functionally the same, and they both use jQuery to manipulate the DOM.
Using Backbone might be overkill for your needs if you're just showing different content based upon what the user clicks on.
Backbone benefits data driven websites where users are creating, editing and deleting data.
The core jQuery library should provide the functionality you need. Checkout jQuery's load method.

Resources