1. Introduction
Recently, I am doing the front-end optimization of a large online banking project. I need to use a fat client optimization. The general idea is that the front-end uses Ajax request to obtain data from the back-end, return it in Jason format, and then display it on the page. Because this system is very large, the fat client solution inevitably requires writing a lot of JS code on the client. I think it is very inconvenient for any team to maintain a large amount of unstructured code. So BackBone came into my sight.
It provides a way to structure your JS code, allowing you to organize your front-end JS code in an object-oriented way. This is like we apply Domain Driven Design on the front end. We can split a very large project by module. Each module can be divided into View, Model, and Router according to the requirements of BackBone.
With backbone, you can treat your data as Models. With Models, you can create data, verify data, destroy or save it to the server. When operations on the interface cause changes in the properties in the model, the model will trigger the event of change; those views used to display the model status will receive the message that the model triggers the change, and then issue the corresponding response, and re-render new data to the interface. In a complete backbone application, you don't need to write glue code to get nodes through special ids from the DOM, or manually update HTML pages, because when the model changes, the views will be updated easily.
2. Features
Backbone is a lightweight front-end framework used to structure the management of a large number of JS in pages, establish seamless connection with servers and views, and provide a basic framework for building complex applications.
Let me briefly explain the main features and characteristics of Backbone:
2.1 Lightweight
Backbone's source code is only about 1000 lines (after decommenting and blank lines), the file size is only 16KB, and the dependency library Underscore is only 29KB.
You only need to spend a little time to easily understand the internal implementation of Backbone; or write a small amount of code to overload some of the mechanisms of Backbone; if you want to do secondary development based on Backbone, it is not a complicated thing.
2.2 Structured
Backbone can easily decouple the data, logic, and views in the page, and organize the code structure according to Backbone. You can assign the data interaction, business logic, user interface and other work in the project to multiple colleagues to develop simultaneously, and organize them together in an orderly manner. At the same time, this is very helpful for maintenance and development of large and complex projects.
2.3 Inheritance mechanism
In Backbone, modules can be inherited. You can organize the data models, collections, and views in your application in an object-oriented manner to make the entire architecture clearer; you can also easily overload and extend custom methods.
2.4 Establish seamless connection with the server
Backbone has built-in set of interaction rules with server data (if you understand REST architecture, you can easily understand them), and data synchronization will be automatically performed in the Model. Front-end developers only need to operate on client data, and Backbone will automatically synchronize the operating data to the server.
This is a very interesting thing because the server data interface is transparent to front-end developers and they no longer need to care about how to interact with the server.
However, the data interface provided by the server also needs to be compatible with Backbone rules. For a new project, we can try to use this set of rules to build the interface. But if you already have a stable set of interfaces in your project, you may be worried about the risk of interface modification.
It doesn't matter, we can adapt to the existing data interface by overloading the Backbone.sync method. For different client environments, we can also implement different data interaction methods. For example: when a user uses a service through a PC browser, the data will be synchronized to the server in real time; when a user uses a service through a mobile terminal, considering the network environment issues, we can first synchronize the data to the local database and then synchronize it to the server when appropriate. And these can be achieved by just overloading one method.
2.5 Interface event management
In MVC, we hope to completely separate the interface presentation and business logic, but for interactive events generated by users (such as click events), we often obtain and bind them through bind methods similar to those in jQuery.
The view in Backbone helps us organize user events and execution methods in an orderly manner, which only requires us to declare a simple expression, such as:
events: { // When clicking an element with id "save", execute the add method of the view 'click #save': 'add', 'mousedown .button': 'show', 'mouseover .button': 'hide' }In an expression, the event name can be any DOM event (such as click, mouseover, keypress, etc.), and the element can be any selector supported by jQuery (such as tag selector, id selector, class selector, etc.).
The view will automatically bind the events in the expression to the selector element. When the event of the element is triggered, the view will automatically call the bound methods in the expression.
2.6 Lightweight template analysis
Template parsing is a method provided in Underscore. Why do I introduce the method in Underscore when introducing Backbone features? Because this method can help us better separate view structure and logic, and Underscore is a library that Backbone must rely on.
Template parsing methods allow us to mix and embed JS code in HTML structures, just like embed Java code in JSP pages:
<ul> <% for(var i = 0; i < len; i++) { %> <li><%=data[i].title%></li> <% } %> </li>Through template parsing, we do not need to splice strings when dynamically generating HTML structures. More importantly, we can manage the HTML structure in the view independently (for example: different states may display different HTML structures, we can define multiple separate template files, load and render as needed).
2.7 Custom event management
In Backbone, you can use the on or off method to bind and remove custom events. Anywhere, you can use the trigger method to trigger these bound events, and all methods that have bound the event will be executed, such as:
var model = new Backbone.Model(); // Bind two functions to custom event custom in the model object model.on('custom', function(p1, p2) { // todo }); model.on('custom', function(p1, p2) { // todo }); // Trigger the custom event, and the two functions bound above will be called model.trigger('custom', 'value1', 'value2'); // Remove all methods bound in the custom event model.off('custom'); // Trigger the custom event, but no functions will be executed. The functions in the event have been removed in the previous step model.trigger('custom');If you are familiar with jQuery, you will find that they are very similar to the bind, unbind and trigger methods in jQuery.
In addition, Backbone supports a special event "all". When an event named "all" is bound to an object, the method bound in the "all" event will also be triggered when any event is triggered. Sometimes this method can be very useful, for example, we can listen for changes in object state through the "all" event.
3. Router
In a single page application, we control the switching and presentation of the interface through JavaScript, and obtain data from the server through AJAX.
The problem that may arise is that when the user wants to return to the previous operation, he may habitually use the browser's "Back" and "Forward" buttons, but the result is that the entire page is switched because the user does not know that he is in the same page.
For this problem, we often use a hash (anchor point) to record the user's current location and listen to the user's "forward" and "return" actions through the onhashchange event, but we found that some lower versions of browsers (such as IE6) do not support the onhashchange event.
Backbone provides routing control function. Through the router provided by Backbone, we can bind the routing address and event function together through a simple expression, for example:
var CustomRouter = Backbone.Router.extend({ routes : { '' : 'index', // Execute index method when URL Hash is in the root directory: url# 'list' : 'getList', // Execute getList method when URL Hash is in the list node: url#list 'detail/:id' : 'query', // Execute query method when URL Hash is in the detail node, and pass the detailed data as parameters to query method: url#list/1001 '*error' : 'showError' // Execute error method when URL Hash does not match the above rules}, index : function() { alert('index'); }, getList : function() { alert('getList'); }, query : function(id) { alert('query id: ' + id); }, showError : function(error) { alert('error hash: ' + error); }, }); var custom = new CustomRouter(); Backbone.history.start();Please try copying this code to your page and access the following address in turn (where the URL indicates your page address):
URLURL#listURL#detail/1001URL#hash1URL#hash2
Please try to use the browser's "Back" and "Forward" buttons to switch back and forth to the address you just entered.
You can see that when the URL Hash changes, the bound method will be executed. When an undefined Hash is encountered, the showError method will be executed and the undefined Hash is passed to the method.
Backbone will record the address changes through Hash by default. For lower version browsers that do not support onhashchange, the Hash changes will be monitored through the setInterval heartbeat, so you don't have to worry about browser compatibility issues.
For browsers that support HTML5 pushState feature, Backbone also allows you to create personalized URLs through pushState, but this requires some adaptation of your web server.
3. Applicability of Backbone
Backbone is not as applicable as jQuery, and if you are planning to build a large or complex single-page web application, Backbone is more suitable.
If you want to apply Backbone to your website page, and there is no complex logic and structure in the page, then this will only make your page more cumbersome and difficult to maintain.
If your project is not complicated, but you deeply like a certain feature of it (may be a data model, view management or router), then you can extract this part of the source code from Backbone because in Backbone, the dependencies between modules are not very strong, and you can easily obtain and use one of them.
4. Dependency library
You cannot use Backbone independently because its basic functions, DOM operations, and AJAX all rely on third-party libraries.
4.1 Underscore
(Required)
Underscore is a basic function library for improving development efficiency. It encapsulates common operations on sets, arrays, objects, and functions. Just like jQuery encapsulates DOM objects, you can easily access and manipulate JavaScript internal objects through Underscore.
Underscore also provides some very practical function methods, such as function throttling, template analysis, etc.
I'll go into details about some of the main methods in Underscore in the next chapter, but before that you have to understand: Underscore is a library that Backbone must rely on, because many implementations in Backbone are based on Underscore.
4.2 jQuery and Zepto
(Optional)
I believe you will definitely be familiar with jQuery, it is a cross-browser DOM and AJAX framework.
For Zepto you can understand it as "mobile version of jQuery", because it is smaller, faster, and more suitable for running on browsers of mobile devices, it is the same syntax as jQuery, so you can use it like you would with jQuery.
Zepto currently only supports browsers with the Webkit kernel, so it is compatible with most mobile systems such as iOS, Adnroid, Symbian, BlackBerry, and Meego, while for Windows Phone or Firefox OS, it is not yet supported.
Because jQuery and Zepto syntax are the same, for Backbone, you have no problem using jQuery or Zepto (of course, you can't use both at the same time).
In Backbone, the DOM selector, DOM event and AJAX all use the jQuery method. The reason why they are optional here is that you do not use the view and AJAX data synchronization function in Backbone, then you do not need to import them.
If you don't want to use jQuery or Zepto, but use other, or custom libraries, as long as your library implements the same DOM selector, event management, and AJAX methods as jQuery syntax, then there will be no problem.
Backbone allows you to dynamically configure the third-party libraries you need to use through the setDomLibrary method, which is often used for:
Although your custom library contains methods with the same syntax as jQuery, the global variable is not $, and you want to keep the existing name. At this time, you can set it to the object referenced internally by the setDomLibrary method.
You want to check the user's environment to decide which library is more suitable for use. For example: if the user accesses using a PC browser, load jQuery, and if the user accesses through a mobile terminal, load Zepto.