Is Backbone.js only for single page applications? - javascript

I'm searching for a simple architecture for my UI that will have some basic javascript functions in like: select all checkbox's, image crop, some pop-ups and some other plugins.
I found this article: Organizing Your Backbone.js Application With Modules
My application is not a SPA (Single Page Application). I want to know if Backbone.js with jQuery will help me even if my application is not a SPA.

The strength of Backbone is really in its ability to manage many models (even complex ones) and keep the rendered page in sync with their current values. It provides an interface to getter/setter functions so that the changing of a model value (there are many different flavors of "change") will call render on the corresponding view and the page will correctly reflect the underlying models. Furthermore, it provides interfaces to saving, paging, and routing actions on models.
I have used Backbone extensively for both SPA's (where it shines) as well as more traditional, multiple page applications. It has no special support for UI and DOM manipulation, but combined with jQuery/Prototype/Zepto it manages their rendering/manipulation.
Basically, backbone works best to untangle elaborate chains of rendering logic and model updating. If you feel that your application has a lot of view elements that need to stay in sync with models that the client will be updating on the page, Backbone is a wonderful solution. If you just need to select and manipulate DOM elements, it's overkill. jQuery alone can handle that.

Backbone is really not about the things you mentioned, but I wouldn't say it is strictly for single-age apps (SPA) either. I'd say it is for any case where you've got quite complicated pages and it would benefit you to break them up into multiple pieces (for example, several views that all pull data from one model).
However, I would say the strength of Backbone.js is in the SPA realm.
You could probably find some jQuery pieces that answer some of your needs if you're not already using jQuery as part of your app. However, jQuery is all about the parts you mentioned (easy DOM manipulation, popups if you use jQuery UI, etc.) and not about structure or organization.

I believe that the principal idea of backbone, is organize you JS code in complex app using the MVC concept.
This way your app becomes easier to mantain and add new features, It get easy to use frameworks tests like jasmine.
Backbone also make possible (and very good) work based on SPA approach, using ajax request to server. It is completely based on Restful concept, to get a code using backbone, is important to understand what is Restful.
Basically Backbone have a Router (that can work like a controller. but is not a controller).
Model that is where you can manage all the data logic of your application.
Collection that is like a list of models.
View that is where you will react accordingly the model changes.
There are other things, but basically, is this.
But as I said before, you can use it without have a SPA.
The most important thing to have in mind is that the concept of MVC must be followed when using backbone. If you don't do that, it doesn't make sense use backbone.

Related

Creating a loosely-coupled & multi-page JS application using Core(Mediator) / Sandbox(Facade) / Module pattern -- advice?

I'm building a multi-page javascript application. I've read a lot into design patterns, and creating applications using a Core/Facade/Module approach w/ loose coupling (pub/sub scribing to events).
I have a pretty good system worked out that minifies & combines all of my module files & related dependencies into a single external javascript file at deployment. Minimizing extra HTTP requests for my application is a design goal -- therefore I'm not too interested in AMD (asynchronous module definition).
I'm using the guidelines delinitated in Nicholas Zakas's presentation,
Scalable JavaScript Application Architecture
http://www.youtube.com/watch?v=vXjVFPosQHw
&&
Addy Osmani's Patterns For Large-Scale JavaScript Application Architecture
http://addyosmani.com/largescalejavascript/
&&
This premium tutorial, by Andrew Burgess from Nettuts, Writing Modular JavaScript
http://marketplace.tutsplus.com/item/writing-modular-javascript/128103/?ref=addyosmani&ref=addyosmani&clickthrough_id=90060087&redirect_back=true
My question is advice on how to go about managing different pages of this application & their associated modules. I'm also using Backbonejs's Router class w/ ballupton's History.js library to manipulate the HTML5 history/state API and dynamically load pages without a refresh while maintaining backwards compatibility for older browsers that don't support the HTML state API. All of my pages share a common code base (single minified & compressed js file).
Here's an outline of the structure I'm thinking of using in my application:
It's essentially a hybrid approach. The top half consists of a Core/Facade/Module pattern with discrete modules that don't interact directly with each other and publish/subscribe to notifications via the facade.
The bottom half consists of my proposed application structure, which notifies a "main controller" when the state/url changes, the main-controller performs any global operations (such as initializing the header & sidebar-menu of my UI if not already initialized) and the instructs the relevant sub-control to run it's init() method (as well as calling destroy(); on any controller that was previously loaded). Each sub-controller (correlates to ex: home-page, calendar-page, reservations-page, etc.) cherry-picks modules from the pool of available modules and initializes them.
Is this a good approach or am I on a bad track? I can see the modules are still independent of each other which is good for scalability.
I've also considered just treating the Router & Controllers as discrete modules and having them publish/subscribe to the Core, and each controller somehow initializes the necessary modules it needs for it's page.
One thing we did to keep history working smoothly was to first change the URL. On change of the URL an event would get triggered, the router would parse the url then figure out what to do. This event would automatically get triggered on page load as well. If you clicked a link it would simply change the URL, which is fairly simple and completely decouples links/buttons from the application logic. This seemed to work well for our application. We used JQM, but we dropped most of their router since we read most of our instructions from some XML file and didn't have a bunch of HTML pages to load into the main viewport area.
I've often seen backbone apps use the router as the core/mediator. This is a good idea. You can simply listen on change events for the URL and then change the page appropriately. This Mediator should probably be a singleton, although singletons are harder to unit test.
The thing I didn't necessarily agree with Backbone on was its definition of "views". The view sort of seems like an action in a controller (well from some perspectives). We added one more level of separation in our application at that point. Our views made ajax requests to template files which were filled in with some JSON and handlebars.js. I'd say your header/sidebar should just be templates. If you need to refresh them then see how you could do extremely simply otherwise you are looking at creating 4 new modules: collection for a list, model for each item, collection view, and model view. I'd couple templates more tightly with some higher level view until they need to be broken down further (eg. some "Application/Main View").
Having this template layer allows you to make superficial changes without recompiling as well, which is nice. Anytime you can put things into "meta" it is a win (well unless it requires you to read XML (ha)). As a bonus you can then cache the template separately as well (or cache bust it separately for that matter).
Your architecture does seem fine though, and is a valid approach to your problem. One tip I'd give is don't over design up front. Iterating is best. You will need to refactor. It is impossible to foresee what would make your application flow more smoothly 3-6 months in advance.
Update on Dec 18th, 2013
Now a days we are using marionette and more addy osmani tricks. On top of the above items we are using AMD's alternate format:
define(function(require) {
var myTemplate = require('hb!mytemplate.handlebars'),
view = require('myview');
...
});
We are also using the marionette application class in combination with wreqr which provides a request/response layer. This allows us to set application wide objects cleanly. It also allows us to define classes without explicitly stating the class name. This is a pretty good way to sandbox. EG:
this.app.setHandler('CanvasClass', function() {
return RaphaelCanvasView;
});
// elsewhere
this.app.request('CanvasClass').text('123', {x:1, y:2});
This all seems to work out pretty well.
You should also checkout aura js and web components. Our directory structure sort of mimics/anticipates those concepts without investing in them yet.
I think it's a good approach.
I've been developing something similar in 2 huge commercial web-apps (minus backbone, and with a custom history manager) and it works great. I'm also not using AMD and all interactions are handled by pub/sub.
One of my best inspirations (which I'm sure you already know) is: https://github.com/aurajs/aura

Backbone.js and jQuery

It is said that Backbone handles all the higher level abstractions, while jQuery or similar libraries work with the DOM, normalize events and so on..
Could someone please help me understand this statement with any simple practical example.
Also one important feature of MVC framework like Backbone, Knockout is that it keeps the model (data) and the view in sync. But this seems to be specific at a page-level and not across the entire application. So can we have the model/data and the view synced across multiple pages..(kind of global)
Your opening sentence was actually a very good statement of the differences between Backbone.js and jQuery, so let's unpack it a bit.
For one thing, the two libraries are not at all in competition--they are complimentary.
As an example, here are some things I would do with jQuery:
Animated slideshows
Form control enhancements, like an iOS-style number "spinner"
Toggling visibility of elements based on a class name
And some things that I might do in Backbone.js:
Create a photo album, where the user clicks on a thumbnail and can view a larger version of the photo, along with some data like the camera that was used, the location and the photographer's name
Build a master/details type of page that presents a grid of data and allows the user to click on individual elements and update them in a form.
jQuery excels at the micro level--selecting page elements, smoothing out the differences in how browsers handle events.
Backbone.js is more big-picture. It helps you manage data and application logic. In the photo album example above, Backbone provides several useful structures: you'd have something to contain all of the data related to photos (a model), a list of all the photos in the album (a collection), and somewhere to put logic that determines what happens when a user clicks on a thumbnail (the view). Those are the main pieces in a Backbone control or application.
Backbone.js benefits from jQuery, though, or something like it, to help render the results of your application's data and logic into the DOM. It's common, for example, to use jQuery to select the element on the page that will serve as the container for your Backbone app. It's also common to use jQuery's $(function () {}); to fire up the pieces of your Backbone control. You'd probably display form field validation error messages with jQuery as well.
You can certainly build big, complex user interfaces in jQuery. We have a few in the app I maintain at work. But they are difficult to work with because jQuery isn't designed to provide structure to an application. In particular, jQuery's API, which is based around selecting groups of items and then passing callback functions that manipulate those items, isn't a good pattern to use in a large, complex control or app. You end up with a lot of nested functions and it's very hard to see what's going on.
I'm currently reworking one of those controls in Backbone.js. As a final example, here's a quick summary of how my thought process differs when working on the same control in both different libraries.
In jQuery, I'm worried about:
Am I using the right selector to grab the group of li elements I want?
Do I need to repopulate that list of values when this Ajax call completes?
How can I put these array values back into the input elements on the page?
In Backbone, I'm more focused on:
What is the correct logic to validate this set of properties on my model item?
When the user clicks the Add button, should I add a new item to the collection immediately, or should I wait until they've filled in all the data and it's "valid"?
How should an item in my collection respond when the item immediately before or after it is deleted?
jQuery handles the nitty-gritty details, and Backbone is more high-level.
In closing, notice I've been using the words "control" and "app" when discussing Backbone.js examples. It's not true that Backbone.js is just for single page apps. It is true, though, that Backbone.js is good for building complex applications that manipulate data and handle a lot of logic. It would be silly to use it for small-scale UI elements--the extra structure it imposes isn't needed.
Update: On the issue of multiple pages, yes, Backbone does provide a powerful mechanism for persisting your data. Each model has a save method that will execute an AJAX call to store the changes on the server. So as long as you save your data as you go, you can have a multi-page app. It's a very flexible model, and it's how we'll probably end up using Backbone at work. While I would love to build a single-page app, we have 10 years of work in our existing multi-page application. We're looking to rebuild some of our more intense UI components in Backbone, then sync the changes to the server before the user moves to a different page.
Backbone / Knockout is typically used for single page applications. So while jQuery is a toolbox that can be used with any webpage, Backbone is meant for a specific type of application and helps you organize your code for it. At least in my experience one of the biggest challenges in building a single page app is keeping the code clean and modular, and backbone helps a great deal with this.
The characteristics of a typical backbone app are:
Essentially static html page, with nothing generated on the server
Server acts as a json REST api, which provides the content for the app
The dom elements to display the data are created with javascript in backbone views, using jQuery and various templating libraries to help
Communication with the server as well as between different parts of the app is done through the backbone models
Regarding your question about keeping the data synced across multiple pages, my instinctive answer is that you don't need multiple pages: the user may perceive that the page is changing, the address in the url bar changes thanks to pushState functionality, but technically the entire app is one page.
The biggest advantages of this kind of approach are a smooth user experience (no reloading pages), good caching support as everything except the json data is static content, for mobile targets the possibility to turn the web app into a mobile app with phoneGap (because everything except json is static).
I have never heard of people using backbone.js across multiple pages. It's almost always some kind of single page app.
The single page may have many different models, views, and states and can result in a full blown, powerful app.
If you already have server-side template/view rendering in java then backbone.js is NOT for you. To get the most out of backbone.js you must move or duplicate some of that code in the front end javascript.
If you don't want to do a single page app (this just means an app without page refreshes or changes, but the url can still change and can look like multi-pages to the user) then you can keep all of your MVC on the server and you have no need for backbone.
Edit:
What backbone does is move some of the MVC stuff normally handled on the server and move them to the client. For many people this means forgetting about the server and just writing your app as a single page javascript app. The server becomes just a source of JSON/REST data. If you're not prepared to do that, then backbone.js is not that useful.
Backbone is a MV* framework while jQuery is a DOM toolkit.
The main features of an MV* application are routing, data binding, templates/views, models, and data access.
Backbone could dependant on jQuery partially.
jQuery is a solid API for querying the DOM with extensive browser support and a vibrant community. It comes with event handling, deferred objects, and animations.
Simple event binding using jQuery
// When any <p> tag is clicked, we expect to see '<p> was clicked' in the console.
$( "p" ).on( "click", function() {
console.log( "<p> was clicked" );
});

javascript frameworks: What are UI bindings and composed views?

I'm reading this:
http://codebrief.com/2012/01/the-top-10-javascript-mvc-frameworks-reviewed/
I'm using backbone.js. I love it, though it requires too much boilerplate. Anyway.
The author of the post seems to put great importance on UI-bindings and composed view.
I think I know the basic advantage of ui bindings, you can change small parts of the view as the model changes without re-rendering the entire view. I don't necessarily see the point though. If your view is huge maybe you should make smaller views? I've seen knockoutjs's code and it's littered with ugly data-bind stuff. How does emberjs handle it? Is there an example?
I have no idea what he means by composed views, could someone elucidate?
Composed Views - Like all software developers, I enjoy creating modular reusable code. For this reason, when programming UI, I would
like to be able to compose views (preferably at the template layer).
This should also entail the potential for a rich view component
hierarchy. An example of this would be a reusable pagination widget.
Is there an example?
Thanks
Edit:
Would this help make something like composed Views?
https://github.com/tbranyen/backbone.layoutmanager
Composed views are used to divide the view into small blocks which can be reused or adapted to different scenarios.
For example, in a form where you are editing a user, you could create a view for the address field and just call it from the main page/template. The author mentions pagination as an example too, in this case you could create a model that knows how to handle retrieving data as you switch between pages and just apply it to a table in your page.
Regarding the "ugly" data-binding code, backbone needs to know how to attach itself to the existing markup and how to modify it when an event occurs.
Maybe this example will help:
http://coenraets.org/blog/2011/12/backbone-js-wine-cellar-tutorial-part-1-getting-started/
Traditional web pages are monolithic. User calls a page and server constructs the page and browser renders it. Here author is referring to breaking down that kind of code in to a set of views. So your page is made up of multiple parts. And each part gets rendered and updated independently. Or one model change can trigger a series of updates on some or all parts.
Basically this allows you to create 'desktop' kind of applications on web. And you don't have to resort to iframe hacks to do this.
Gmail and Google Reader are good examples of web applications built with composed views.
I created LayoutManager for Backbone.js because I too wanted to composite views.
http://tbranyen.github.com/backbone.layoutmanager/
Let me know if you find this approach helpful.
It sounds to me like the author is talking about server-side code here. Building a system of reusable page templates, that generate pages from a common set of widgets, html snippets, etc...
Apache's Tiles is one way of doing this.

Do I have to use a Backend when using Backbone.js?

I want to develop a relatively simple application that calculates some value based on several inputs. I dont want a backend, all the calculation can be done in the browser.
Im a little new to JavaScript and WebApps and I came across Backbone.js.
I really like the MVC design, however, they mention a backend a lot. My question:
Is a backend server absolutely required?
Is a backend server optional but without one there isn't much point in backbone.
Or will backbone will really help me out?
Backend is not required.
Backbone can fully work without any backend if your application doesn't require one.
That depends on your application. If you want to retrieve value of some inputs and calculate a result then Backbone won't do that for you - it will help you structure your code. If you app is simple and don't need support for models, views and collections or routing, then there is no point in using Backbone. Hard to answer this question.
For example: Classic todo example application doesn't use any backend.
Backbone.js implements fetch(), save(), destroy() etc. methods on models automatically performing appropriate AJAX requests and parsing response. So it has a strong support for backend via REST services, but it is optional.
You can still use models, views, routers and events without any server-side code. Just don't call REST methods (or override them at your wish).
You can use localStorage for persistence (you'd have to implement this yourself or find it on the web, like here) but if you don't even need that then you don't need to use any of the persistence methods in backbone.
Backbone is meant to help you structure a medium-large sized application (js-wise), so it doesn't become unmaintainable jQuery spaghetti. With short applications (js-wise) it's really an overkill unless you are trying to learn how backbone works.
Note with js-wise I mean the client side code, if you had a huge backend but the only js would be something that focuses some form, it would not even count as a short application (js-wise).
You can use backbone.js without a backend. However you obviously won't be able to store or retrieve data. Backbone may still be useful for keeping your code organized, however it really shines when you want to separate presentation logic from logic that manipulates your data, which is a goal of the MVC pattern. Generally your data will be stored on and retrieved from a backend.
If you want to play around with data persistence, try out backlift.com. [disclosure, I work on backlift.com] We've tried to make it easy to get a backbone app up-and-running without having to setup a server or deal with compiling templates.

Best way to separate data from DOM

I have this time tracking / task managment tool I'm working on called Task Ranger. Basically you make a tree of tasks and sub-tasks, click on whichever task you're currently working on, and your time for that task is tracked.
I want to add a feature where the user can look at their times for a specific date range (ie. "What did I spend my time on last week?") I'm thinking I want to have a tab that I can click to jump from the "Main" view to the "History" view.
The problem is that right now I'm persisting my data by simply storing everything in the DOM and dumping the entire html structure into localStorage. In order to get the history view to work I'm going to need to separate the data from the html, right? I guess an MVC framework is the typical way of doing that, right? I was looking at Backbone, but I'm feeling like it might be a little overkill for this. I'm thinking maybe I should roll my own simple little thing. What do you think?
I'm using Javascript + Jquery for all of this right now.
Backbone is about as lightweight as you can get MVC. If I were to write my own micro MVC framework it would convert to backbone within a week.
I would highly recommend Backbone over writing your own because it's well structured and loosely coupled. You can only use the features of backbone that you want. Since your already including jQuery there is little overhead of including backbone aswell.
Backbone is great for structuring and organizing your code.
You can use the backbone-localstorage adapter to save your models to localStorage.
You can then save a backlog of all your models or get them from a RESTful server for your history view.
A solid alternative to backbone would be spine which is also a lightweight MVC library. Spine has a more traditional MVC attitude and is only 2kB

Categories

Resources