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

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.

Related

Ionic modal with state

Is there any way to make an ionic modal have a ui router nested state with multiple modal pages?
It sounds like you are describing a wizard, A model that has multiple pages (or steps). Because Ionic and AngularJS go hand in hand with each other you can use some of the pre-built AngularJS components to achieve this, here is a link to a few:
https://github.com/mgonto/angular-wizard
https://github.com/simpulton/angularjs-wizard
There is an ionic wizard plugin, which although it is designed for wizard like steps, will pretty much provide a set of linked modal pages which share state, which should meet your needs.
http://arielfaur.github.io/ionic-wizard/
It also has nice features such as preventing progression in a wizard until fields are filled out etc.
I would recommend not doing that because I have tried it in the past and in the end I realized that it wasn't really practical. What you could do is, add:
ng-include src="'your-template.html'" ng-controller="yourTemplateController">
Now you have a view and a controller associated with it. All that is left to is, make the URL change. This can be done by using location.hash, or setting $stateParams and checking for it using $watch. I hope this helps.

Doubly nested views : UI-Router or UI-Bootstrap tabs / accordion?

I am a total Angular (and JS) beginner.
I want to develop something like this:
(with apologies to #PhillipKregg for borrowing his excellent illustration).
Effectively, I want nested tabbed notebooks - a row of tabs (views?), each which can contain data or another row of tabs (each of which ...).
Googling seems to return more recommendations for UI-Router, but I imagine that UI-Bootstrap's Tabs or Accordion could also be used (or even UI-Bootstrap's Pagination, with a single view whose contents I update according to the selected page?).
All else being equal, I will go with whichever is easiest for a novice to understand and implement (which is that?).
But - are there performance issues? For instance, will one download the content of all the views immediately or initial page load (thus increasing initial page download time)? Will one only download the data for a view when it becomes active (which seems preferable)?
Anything else I need to consider?
Yes, ui-router & ui-bootstrap.tabs are the best tools for the job at the moment. To do something similar would require mixing two types of ui-router config patterns, nest views & multiple named views. I'd suggest reading both these wiki pages:
https://github.com/angular-ui/ui-router/wiki/Nested-States-&-Nested-Views
https://github.com/angular-ui/ui-router/wiki/Multiple-Named-Views
Here's a basic draft demo of something similar to your illustration, using ui-router & ui-bootstrap.tabs: http://plnkr.co/edit/BUbCR8?p=preview
The easiest way to get started is to use ng-boilerplate https://github.com/ngbp/ngbp, it uses ui-router & has best-practice directory structure. It also addresses performance issues by compiling html to js & adding templates to $templateCache, thus kicking lots of XHR requests to the curb.
Regards to data downloads, data would typically be managed by a angularJS service singleton instance, separate from any views. How & when you invoke any service from any view is totally your choice. This is a pretty good tutorial on angular services: http://www.ng-newsletter.com/posts/beginner2expert-services.html
I would recommend to use angular $routeProvider for your task. This will make easy to handle code and view fragments.
With bootstrap you will need to put all the code on single page and that is less manageable. Have a look at
http://viralpatel.net/blogs/angularjs-routing-and-views-tutorial-with-example/ and
For nested views
http://www.bennadel.com/blog/2441-Nested-Views-Routing-And-Deep-Linking-With-AngularJS.htm
Also $routeProvider is better for navigation. Back Forward through view...
Angular will load views when required.(Lazy loading.) So better for performance...
Hope this will help.
I personally don't get the point of wanting to use bootstrap tabs with angular's ui-router. It is counter-intuitive. Just don't use bootstrap's tabs and set up the "sub-tabs" in the angular config. This will also make your code more readable. Only add ui-bootstrap if you NEED the extra features. An example config is below
$stateProvider.state('A', {
url: "/A",
controller: "testController",
templateUrl:'pages/A.html'
})
.state('A.B', {
url: "/A/B",
controller: "testController2",
templateUrl:'pages/A.B.html'
})

Jinja2, Backbone.js and progressive enhancement

I have a working website build on top of Google App Engine (Python + Jinja2 template engine). I would like to start redesigning it to be single page application using Backbone.js and Underscore.js. The goal is to use progressive enhancement strategy.
The site will still be rendered using backend on the first visit. And then if the browser supports JavaScript the Backbone.js will take over.
I decided to do it this way for two reasons. First all the links I already have will stay intact and second the Google indexing bot will be able to crawl the site content.
I have two problems with this approach:
I need to have two templates for almost everything on my site one on the backend (Jinja2) and one on the frontend (Underscore.js). I was wondering what are the best practices in cases like this? Is there anything you can suggest to avoid having two templates for everything?
How do I load the templates for the frontend to use Backbone.js + Underscore.js? I can load them all in the initial request or request them asynchronously when they are needed.
I appreciate any thoughts!
Thanks.
Some resources:
http://ricostacruz.com/backbone-patterns/
This one describes how to bind Backbone.js to existing HTML:
http://lostechies.com/derickbailey/2011/09/26/seo-and-accessibility-with-html5-pushstate-part-2-progressive-enhancement-with-backbone-js/
So I recently(this year) went through a similar situation. I'll let you know a head of time that #1 is an incredibly tough thing to deal with. Keep in mind, that you not only would have to duplicate your templates, but ALL business logic surrounding your site. For example, let's say you allow users to add comments on a particular page. Using the method you described, you would have to both have a comment template on the server-side and the client-side, and additionally, duplicate the logic required to add/delete/edit a comment on both the client and the server(to accommodate users with and without javascript). Duplication of the templates is easy using Jinja2 function blocks, but the duplication of the logic is where it gets interesting. I attempted to do just that, and ended up doing a full re-write a few months later.
So the advice I would give to you is ditch the idea that you can support both javascript and non-javascript users. Make your site for one or the other. I personally chose to go the javascript route myself. This leaves you with two options. Make a single page app, or make an app that largely leverages javascript for functionality, but renders everything server-side. There are probably a number of other options, but those are the two most popular that I have seen. I went with the second option. So what I do, is the initial page load is done by the server. Backbone.js then consumes each element and makes models and views out of them. This is largely done leveraging data attributes. So for example to create a comment view I would have an element like this:
<div class="comment" data-id="1" data-body="You Suck"></div>
I would then consume said comment, and create a model out of it like so:
var CommentModel = Backbone.Model.extend();
var comment_el = $('.comment');
var comment_model = new CommentModel($(comment_el).data());
Finally, I would back a view with that created model, which can then add functionality to the site:
var CommentView = Backbone.View.extend({
initialize: function() {},
edit: function() {},
delete: function() {}
});
var comment_view = new CommentView({
model: comment_model
});
Then you might be asking, "What if I need to re-render something, don't I need client-side templates for that?" Nope. Client-side templates are a pretty new thing. I personally try to avoid them as I don't think we're quite there yet, and I have always felt that single-page apps are just not responsive enough for my tastes. I'm sure there are plenty of people who would disagree with me on that, but that's the stance I took with my most recent project. So that being said, I render everything on the server and send the html to the client in the form of JSON, which I then inject into the DOM. So I have a ton of api endpoints, which return JSON to my Backbone.js code. This is what is currently working out for me, but this problem is largely situational usually. You have to really look at what your needs are. For it's worth, I largely based my current system off of what Twitter eventually decided to do after trying the whole single-page app thing. You can read about it here.

is it advisable to have every part of a page as a backbone view template?

Im making a webview app for iOS & Android using Backbone.js. I'm bit new to Backbone
I have seen some examples where they have used backbone's view template for every section of a particular page/view even if those sections are just static texts or images. I'm not sure if thats the right way to do it. In my opinion one should write a view as a template in HTML only if it's going to dynamically change in its presentation, with the help of variables, etc. Otherwise, the usual structuring of HTML elements is good enough.
Pls provide your inputs.
Thanks.

Reusing Backbone.js controls and widgets

Is there a good model for reusing UI components written in Backbone.js?
My team maintains a large web application that is mostly written in server-side code, but we're finding that we're doing more and more client side work. We have several large UI components that were written in jQuery, and they're really too complex to maintain with just a DOM manipulation library. We need a client-side application framework.
One nice thing that the jQuery plugin model offers is ease of reuse. You can just create a few HTML elements with the appropriate IDs and wire them up with $(function(){}). We'd definitely need to achieve something similar with Backbone if we adopted it.
Most of the examples out there show how to build an application entirely in Backbone, which is great, but we're not going to be reimplementing our app in JavaScript anytime soon. Our use of a client side framework would be confined to complex UI controls with a lot of business logic in them.
One other consideration is that we have a JavaScript bundling solution in place. I'm concerned that bundling a lot of Backbone elements together could mean that we end up with headless controls loading and running in the background.
Can you build Backbone controls and package them as jQuery plugins? Are there any good resources available about this kind of architecture?
For me one of the best parts of using Backbone is essentially what you are describing. The object-oriented-ness of Backbone makes it really easy to build out a specific 'widget' or other reusable code piece that you can bind events / templates / data to. You wouldn't necessarily want to make these jQuery plugins, simply because it wouldn't provide much benefit over Backbone's syntax.
For example, you could build a control class, and bind a click event to trigger the foo method on it.
var Control = Backbone.View.extend({
id:null,
events: {
'click' : 'foo'
},
foo: function(){
console.log(this.id);
}
})
Every time you want a DOM element to use this behaviour, you create a new Control object, and bind it to the element using jQuery.
//I say foo when you click me
var foo = new Control({el: $("#foo"), id:'foo' });
//I say bar when you click me
var bar = new Control({el: $("#bar"), id:'bar' });
(You feasibly could wrap those calls into a jQuery plugin)
This a really simple example to show what the workflow would be, you can get really intense with Backbone's models/collections and Underscore's templating engine to create some really robust dynamic & reusable classes.

Resources