Reusing Backbone.js controls and widgets - backbone.js

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.

Related

How to Combine Backbone with Meteor

I'm currently working on a complex single page web app. It's something like a charting program: you can select or add objects on a white page. There's many types of objects. If you select some of type A objects, then it will add/remove B/C/D objects based on a complex logic. I'm currently using Backbone.Model for these objects. And Backbone.View for displaying. It's a pretty standard MVC structure, with models for objects data, controllers for managing models and views, and views for displaying. It's all using DOM elements. The views are added, removed or updated (with CSS) based on model data.
It works great and now I'm trying to add server side to save and load all data to/from the server. I planned to write a REST API server with restify for all the models.
Then I find meteor.js, the 'realtime', 'reactivity' and 'database everywhere' features intrigue me. So it will greatly simplify my app if I can save and load my models directly and let meteor to do the sync. And the real time feature can be a great plus for my future features, such as adding realtime collaboration.
But it seems meteor has a very different idea from Backbone on how a web app is structured. How can I combine meteor with my current Backbone code? Do you have any great suggestions?
Thanks.
Uh, don't. Do meteor all the way, or do backbone, but meteor is pretty much a combined full-stack solution not really intended for use with something like backbone. Meteor already provides deeply-integrated components that address all the areas that backbone addresses (data sync, DOM updates, etc).

How does the Canvas work with MVC Frameworks?

I've been looking into AngularJS and its MVC solution. Typically a MVC framework uses the HTML structure itself to bind to a backend data model. In AngularJS's case this is done with Directives, which work dandy for straight HTML.
For my scenario I have a data model that will be transmuted into a visual representation on an immediate mode Canvas. Then the visual items rendered will also need to be interacted with in order to edit the values in the backend data model.
What is the best way to achieve two way binding like this between items and the item values in a data model within a MVC framework?
Angulars strength is that it deals with the DOM for you without you having to worry about it. If you were to use SVG instead, you could let Angular deal with updating the view since SVG is DOM but if you need to use a canvas instead, Angular can't handle the drawing for you.
You can still benefit from using Angular by using watches and redrawing your canvas when data changes, but you need to deal with the drawing yourself.

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.

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