Initial Backbone.js on Force.com Issues

Thursday, December 15, 2011

I spent a fair amount of time the last day or two working on creating a Visualforce page that uses backbone.js as an intermediary for communicating with the Apex controller via Ajax calls. I am still doubtful whether this framework will prove to be a good way to interface with Salesforce objects and data, but I won't know until I finish.

Now, much of the time I've spent so far has been to connect the several backbone.js objects. They are: the model, the view, the controller, the HTML templates, and their duties to one another.

While backbone.js is a framework that follows the MVC pattern, backbone's view serves a different purpose than the view in other frameworks, such as Salesforce's own MVC framework of Visualforce and Apex. The purpose of Backbone's view is to bind to an HTML element, and, when appropriate, render data from the model into this element using an HTML template.

Did you also notice the interesting bit here? There are actually two views in play here! The HTML is the true (or truer) view, while the backbone.js view supplies the HTML view with logic, acting almost like a controller.
So if the view is a controller in backbone.js, then what is the controller? Well, in backbone.js, the C represents collection, which is a "smart list" that holds backbone models. Likewise, backbone models are simply Javascript objects, nothing more!

Well, that's a slight simplification, since each of these backbone objects has a bit more responsibility than I explained above. I'll explain the jobs/responsibilities of each of these backbone.js objects in my next post. For now, I want to discuss a few of the issues I've encountered.

The first problem I was having was with jQuery. It is usually necessary to use jQuery in no-conflict mode, and to alias it to a variable that is not '$', such as '$j'. Having said that, Backbone has two other Javascript libraries as dependencies, Underscore.js and jQuery, and uses them extensively under the covers. I had some problems with using no-conflict mode here, but this was solved with a few well-known tricks. Here is one way to solve the problem. This great blog post has some other solutions.

The other problem is that Backbone.js is built to use a RESTful way of GETting data from and POSTing data to the server. So naturally, I started writing a @RestResource class that will respond to these calls to retrieve data and update data in the database. This is one place I started to encounter problems - these REST handlers are located at na4.salesforce.com/services/apexrest/, which is a cross-site-request from the Visualforce page at c.na4.visual.force.com/apex/. Still not positive this is the problem, but I'm pretty sure. To resolve this, I will attempt to handle Backbone's sync calls with Javascript Remoting.

Backbone proved to be too complex for me. I started using Knockout, and it's been really great. I have working code for Knockout that connects to my REST endpoints, if you're interested.https://github.com/chexxor/knockout-mapping-sfdc-rest

When I was working with Backbone, I was always confused about what was my responsibility as a developer and what Backbone did for me. In retrospect, this can be answered by saying that Backbone is a library, not a platform. That is, it is just a way of thinking, a pattern, about how to solve universal Javascript app problems.

Having said that, I much prefer Knockout for writing simple Force.com JS apps. While Backbone is good if you want to use complex templating, Knockout makes your code much cleaner because it hides the complexity, like a good little platform should do. You don't have to think about writing HTML when you use Knockout, which was the biggest source of confusion and frustration for me when I was using Backbone.