BackboneJS framework skills and models (3)

Source: Internet
Author: User

This article is followed by the second part: skills and models of the BackboneJS framework (2)

Http://blog.csdn.net/chszs

4. Page refreshing

When developing applications using Backbone. js for the first time, the typical view structure is as follows:

var View = Backbone.View.extend({    initialize: function(options) {        this.model.on('change', this.render, this);    },    template: _.template($(‘#template’).html()),    render: function() {        this.$el.html(template(this.model.toJSON());        $(‘#a’, this.$el).html(this.model.get(‘a’));        $(‘#b’, this.$el).html(this.model.get(‘b’));    }});

Any changes to the Model will trigger a full refresh of the entire view. When I first used Backbone. js for development, I was a practitioner of this model. However, as the view code grows, I quickly realized that this method is not conducive to maintenance or optimization, because when any attribute of the model changes, the view is completely refreshed.

When I encountered this problem, I quickly searched Google to see how others did it. We found Ian Storm Taylor's blog, "breaking down the Backbone. js rendering method ", which describes listening to a single attribute change in the model, and then simply re-rendering the part that is relative to the attribute change in the view. Taylor also describes the reference of the returned object so that a single rendering function can be easily linked together. The example above can now be modified for easy maintenance and better performance. Because we only need to refresh Part of the view.

var View = Backbone.View.extend({    initialize: function(options) {        this.model.on('change:a', this.renderA, this);        this.model.on('change:b', this.renderB, this);    },    renderA: function() {        $(‘#a’, this.$el).html(this.model.get(‘a’));        return this;    },    renderB: function() {        $(‘#b’, this.$el).html(this.model.get(‘b’));        return this;    },    render: function() {        this            .renderA()            .renderB();    }});

I would like to remind you that there are many plug-ins, such as Backbone. stickIt and Backbone. modelBinder allows you to bind model attributes to the key values of view elements, which saves you time to write a lot of sample code. Therefore, if you need to implement complex form fields, you can look at these plug-ins.

5. Keep the model irrelevant to the view

As Jeremy Ashkenas pointed out in the GitHub issue of Backbone. js, Backbone. js does not implement real separation between the data model and the view layer unless the model is not created by referencing the view. Because Backbone. js does not implement any separation of concerns, should you separate them? Me and many Backbone. js developers, such as Oz Katz and Dayal, all believe that the answer is undoubtedly yes: the model and set, that is, the data layer, should be completely irrelevant to the view bound to them, maintain a clear separation of concerns. If you do not follow the separation of concerns, your code library will soon become pasta-style code, but in fact no one will like pasta-style code.


Keeping the model irrelevant to the view will help you prevent pasta-style code, and no one will like pasta-style code!

Keep the data layer completely independent from the view layer, which allows you to create a more modular, reusable, and maintainable code library. You can easily reuse and extend models and collections across applications without considering the view they are bound. Following this pattern allows new users who are not familiar with the project to quickly dive into the code library, because they will know exactly where rendering occurs and where the business logic exists.

This model also implements a single responsibility principle-it specifies that each class should have a single responsibility, and its responsibilities should be encapsulated in the class, because the model and set are responsible for processing data, the view is responsible for rendering.

Vi. Route parameter ing

The best demonstration of this mode is to understand the entire example. For example, you can sort the results on the search page. The search page allows you to add two different filter types, foo and bar. Each type represents a different filter rule. Then, your URL structure should be like this:

'search/:foo''search/:bar''search/:foo/:bar'

Currently, all routes use the same view and model, so most people prefer to use the same function search. However, if you have checked the Backbone. js code, you will find that there is no sort of parameter ing in it; these parameters are just passed into the function from left to right. In this way, to use the same function in a unified manner, you need to stop creating different functions and map the parameters to search () correctly ().

routes: {    'search/:foo': 'searchFoo',    'search/:bar': 'searchBar',    'search/:foo/:bar': 'search'},search: function(foo, bar) {    },// I know this function will actually still map correctly, but for explanatory purposes, it's left in.searchFoo: function(foo) {    this.search(foo, undefined);},searchBar: function(bar) {    this.search(undefined, bar);},

As you think, this mode can quickly expand the routing function. When I encountered this problem for the first time, I tried to create some regular expressions to parse the actual function definitions to implement parameter ing. Of course this can work-but it is also constrained. Therefore, I gave up my idea (maybe I can still solve it through the BackboneJS plug-in ). On the Issues page of GitHub, we recommend that you map all parameters to the search function.

The above code can now be modified to the following code with stronger maintainability:

routes: {    'base/:foo': 'search',    'base/:bar': 'search',    'base/:foo/:bar': 'search'},search: function() {    var foo, bar, i;    for(i = arguments.length - 1; i >= 0; i--) {        if(arguments[i] === 'something to determine foo') {            foo = arguments[i];            continue;        }        else if(arguments[i] === 'something to determine bar') {            bar = arguments[i];            continue;        }    }},

This mode can significantly reduce the excessive expansion of routes. However, it should be noted that if it cannot recognize a parameter, it will not work. For example, if you have two parameters with IDs, such as the pattern XXXX-XXXX, then you cannot tell which ID is the response to which parameter.

7. model. fetch () will not clear your model

Generally, this will cause problems for beginners of Backbone. js: model. fetch () does not clear your model, but inherits the attributes of the model. Therefore, if the model has attributes x, y, and z, And you retrieve y and z, the attribute x is still the x in the model, and the attributes y and z are updated. The following example illustrates this:

var Model = Backbone.Model.extend({    defaults: {        x: 1,        y: 1,        z: 1    }});var model = new Model();/* model.attributes yields{    x: 1,    y: 1,    z: 1} */model.fetch();/* let’s assume that the endpoint returns this{    y: 2,    z: 2,} *//* model.attributes now yields{    x: 1,    y: 2,    z: 2} */


Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.