15 years ago, many people used tools such as Perl and ColdFusion to build websites. We often write scripts that can query the database at the top of the page, apply the necessary transformations to the data, and display the data at the bottom of the same script. This type of architecture is appropriate for adding a simple "contact us" form to a Web site. However, as applications become more complex, this approach cannot be scaled to deal with larger and more complex problems. Most WEB applications now standardize the model-view-controller (MVC) architecture, using separate code to implement business logic, display logic, and user interaction (routing) logic. A variety of frameworks emerge from Spring MVC to Rails to help you quickly implement an MVC based WEB application.
A few years ago, JQuery was the mainstream repository for building client JavaScript applications. However, as the complexity of JavaScript in the application grows, jQuery becomes a necessary and inadequate technique for dealing with complexity. For example, a to-do application for a to-do list can contain an urgent to-do list, a complete to-do list, a day to Do list, and a list of expected to-do items. What happens when you delete a to-do item? If the task is urgent but has expired, you may need to write code manually to remove the item from three or four different locations in the view. If you delete an object and you need to delete or change other related objects that appear on the screen, the complexity becomes uncontrollable.
The client MVC framework is designed to address this type of problem, and most frameworks perform well. But how do you choose the right framework from a number of JavaScript client MVC frameworks? This article will briefly introduce some of the most popular frameworks from a higher level. And how to choose the appropriate framework for a given use case.
Backbone.js
In terms of usage, backbone is by far the most popular client MVC framework. It is widely used in various development communities, and Rails developers have a high adoption rate and many popular resources, such as Thoughtbot (a respected Rails consulting firm) has launched backbone on rails (see Resources). The advantage of Backbone.js is that it integrates well with the representational state transport Web service. If you use the RESTful JavaScript Object notation (JSON) model for back-end data and follow the conventions expected by backbone (which match the conventions in Rails), you can connect backbone to a service without writing any code , thus saving a lot of time.
In backbone, an application contains collections (users or articles), models (individual users or articles), views, and routers. The views in Backbone.js are not predefined (nonprescriptive), allowing you to use your favorite JavaScript templates or frames. Routers combine Rail-style routers and a traditional MVC controller, which is responsible for obtaining the given URL and informing the framework to run the code. The Backbone.js router code in Listing 1 gives an example.
Listing 1. Sample Backbone.js Router Code
var Workspace = Backbone.Router.extend ({
Routes: {
"Help": "Help",//#help "Search/:query": "Search",//#search/kiwis "search/:query/p:page": "Search"//#search/KIWIS/P7 },
Help:function () {
....
},
Search:function (query, page) {
.....
}
});
Backbone.js comes with a underscore.js copy. Underscore.js is a set of utilities that simplifies the authoring of JavaScript in a more functional way and supports a series of useful, collection-based operations. It also includes Backbone.history, which can help you handle page navigation intelligently.
The main advantage of Backbone.js is its automatic integration with the server. If this is appropriate for your use case, it would be worthwhile to learn how to use Backbone.js. You can use some framework to get a backbone.js basic knowledge that may take a day or a two to learn in a few days. This is ideal for larger projects, which last for at least a few weeks.
Backbone.js is still not a perfect solution. You may need to write a significant amount of code to handle potential memory leaks, and so on. You may also need to experiment with several methods to see what is being rendered before you can find a way to really meet your needs.
Spine.js
Spine.js are usually compared with backbone.js, which is influenced by Backbone.js and is close to the former in terms of usage. Spine.js contains classes, models, controllers, and views, which are more traditional than the collections introduced by Backbone.js.
Spine.js is written using coffeescript (see Resources), which makes it more concise and, in my opinion, easier to read source code. To understand how spine.js works, you need to be familiar with Coffeescript. However, you do not have to use Coffeescript to build spine.js applications. However, if you have built with Coffeescript, you can access the Coffeescript attributes (such as classes). Coffeescript uses prototype inheritance rather than classic inheritance, and therefore cannot support classes in local JavaScript. Coffeescript uses some very standard patterns to provide classes for developers who want to use them. If you write spine.js applications using pure JavaScript, you only need to use them, which allows you to access the class without writing Coffeescript code.
The models, controllers, and views in Spine.js use class implementations, so you can write both classes and instance methods. The model is responsible for handling business logic, which belongs to the module class, and you can extend and include other modules to mix and reuse properties and functionality. Models can be automatically serialized into JSON and persisted by using only local storage. Alternatively, you can use asynchronous JavaScript + XML (Ajax) to persist objects to the server. Like Backbone.js, Spine.js now provides a reasonable default setting that can be persisted through Ajax, but can still write your own specific implementation if necessary, and is very simple. Listing 2 shows an example of the Coffeescript code from a spine.js application.
Listing 2. Coffeescript in the Spine.js application
Class Contact extends Spine.model
@configure "Contact", "first_name", "last_name"
@filter: (query)->
@select (c)->
C.first_name.indexof (query) is not-1
FullName:-> [@first_name, @last_name].join (")
The main difference between spine.js and backbone.js is how they handle server interaction. Backbone.js waits for the server to respond before displaying the response. If you attempt to delete, insert, or update an element, the user interface (UI) is not refreshed until the operation completes successfully. Spine.js focuses on immediate updating of the UI and handles Ajax servers while doing background processing. This update is a very important practice and a major factor to consider when choosing between the two optimized popular frameworks with good documentation.
If your goal is to create a client experience, and updates to the server state are secondary, then spine.js may be a better choice. Backbone.js may be more appropriate if you still use the server to check the validity of state changes. Spine.js provides a more responsive UI. However, what happens if the display succeeds in deleting an element and simply having the server send a response that does not allow you to delete the item because it is being used by someone else? There are some contingency plans for this problem, but generally speaking, spine.js is more suitable for users to manipulate their own (rather than share) data. A common use case for spine.js is the shopping cart, where all validation can be handled on the client side.
Knockout
One might argue that the tools discussed so far are the true MVC framework in the original sense. Knockout explicitly implements the model-view-View-Model (MVVM), rather than the classic MVC. However, do not hinder your decision making. When you select a frame, it is more important to view the features that are provided rather than acronyms or classifications.
Knockout.js is particularly popular among Microsoft. NET developers who are familiar with the MVVM model. Knockout.js is a great choice for the main problem of binding the model State to the view use case declaratively. Knockout.js for the example to-do application mentioned earlier, the application's subset of the main to-do list has its own view, and all the lists need to be updated after a to-do item is deleted.
In Knockout.js, you will create models, view models, and views. As in Spine.js and Backbone.js, Ajax is responsible for handling business logic, validating, and interacting with remote servers (assuming you are not just creating a local application). The view model code is responsible for preserving and manipulating model data. For example, a view model might contain methods for adding, editing, and deleting content items from a list. The view model is very close to the controller in the traditional MVC architecture. A view is a template that contains the markup that renders information to the screen. In Knockout.js, these can be declaratively bound to the view model (easy to get started). Some trainees can master and use knockout within one hours, and can build extraordinary (non-trivial) applications within three hours.
Generally speaking, knockout.js is more suitable for smaller, simpler projects. People tend to use backbone.js or spine.js for larger, more complex projects. That is to say, experienced knockout.js developers can create very complex and maintainable applications. If you consider using Knockout.js, you should also consider Angular.js and sammy.js (see Resources), which are two relatively lightweight, easily bootable frameworks.
Batman.js
Batman.js is an interesting new framework that was introduced by Jsconf in 2011, but it took several months to download. Batman.js has begun to receive the attention of programmers who like and have developed MVC applications. On the surface, Batman is similar to knockout.js in terms of easy entry and support for view-declaration bindings. Batman.js offers additional features, including an optional full stack (full-stack) framework for automated code generators, build tools, and even back-end Node.js server code to implement your server-side APIs.
Like Knockout.js, Batman.js also uses view bindings. Listing 3 shows some sample view code.
Listing 3. Example of view code in Batman.js
<ul id= "items"
<li data-foreach-todo= "Todo.all" data-mixin= "animation"
Lt;input type= "checkbox" data-bind= "Todo.isdone" data-event-change= "Todo.save"/>
<label data-bind= " Todo.body "data-addclass-done=" Todo.isdone "
data-mixin=" editable "></LABEL>
<a data-event-click= "Todo.destroy" >delete</a>
</li>
<li><span data-bind= " Todo.all.length "></span>
<span data-bind=" ' Item ' | pluralize Todo.all.length "></span> </li>
</ul>
The code in listing 3 is a valid HTML5 that contains some additional attributes for Batman binding data and events. In Batman.js, your application contains models, views, and controllers. The model supports validation and enables lifecycle events to be implemented, including a built-in identity map, and can be told how to persist, or customize the implementation of (active record style Batman.RestStorage
) Batman.RailsStorage
. Views are JavaScript classes that present templates written in plain HTML, as well as artifacts that data-*
bind model data with attributes and trigger event handlers. The controller is a permanent object that handles events from the view, accesses the model data, and renders the corresponding view.
Choose a JavaScript framework
If you are working on a large long-term project, it is necessary to understand backbone.js or spine.js because they are widely adopted to solve the problems you may encounter. However, even with these projects, you need to understand that you are not necessarily using a full-fledged server-side MVC framework, but that you need to continue writing the underlying schema code.
It is necessary to try to use a framework that is declaratively bound in a view. Such frameworks have different advantages and disadvantages from projects such as Backbone.js. If you consider using declarative view bindings, spend some time looking at the additional functionality provided by the updated Batman.js framework. Although Batman.js is not as popular as other frameworks, it is developing rapidly and provides richer features than the common client MVC framework.
It is necessary to prototype in different frameworks and feel the use of these frameworks. Especially for the client MVC framework, prototyping is one of the quickest and most efficient ways to choose from different options. One way to do this is to have each team member spend one or a day using different frameworks for prototyping, and then review and discuss the results. At worst, if you have a couple of frameworks you need to choose from, then spend a day or so to build the concepts of both until you choose the framework that best suits your use case.
Consider flexibility. It is a daunting task for many frameworks to think carefully about what you can do to reduce your dependency on the framework. Develop a backup plan for migrating to another framework in the next six to 12-18 months in case you find that the requirements and the selected framework are not as expected.
Conclusion
The JavaScript client MVC framework is still not mature enough. There is a rapid change in this area and lack of consistent best practices. For larger projects Backbone.js and spine.js are very popular and have good support. If you tend to declare view bindings, then knockout.js and batman.js are good choices.