`
since1027
  • 浏览: 9108 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

Part 6: Understanding Backbone.js Views

阅读更多
In this article, we will try to look at the View classes in Backbone.js and see how view classes help us in updating the relevant parts of the application easily.

Background

The biggest problem while writing JavaScript applications is the spaghetti code that one needs to write just for HTML DOM manipulation. Every element on the UI will need some actions to happen when the user interacts with them. Some UI elements would want to automatically update the values based on the new/updated data. Doing all this using plain HTML and JavaScript/jQuery is a big problem (doable but nightmare) specially from maintenance perspective.

Backbone.js view greatly helps us when it comes to creating large scale manageable applications. The view classes are more like a glue that holds an HTML template with the model object. Also, this provides the mechanism to handle the events raised from the model and update the UI and handle UI events and act on them (perform some operations on the model). So in a way we can say that the views are just observers who are listening to the model and UI events which makes them a perfect place to handle all the events and act upon them. Backbone views can be thought of as:

Observers that keep listening to the DOM events and in case the event fires taking the appropriate actions.
Objects backed by models that are responsible for rendering the model data on the screen.
Let us see how we can use backbone.js views to efficiently manage the applications.

Link to complete series:


Using the code

Creating a simple view

Let is start the discussion by looking at how we can create backbone views. Like backbone models and collections, creating a backbone view is also as easy as extending the existing Viewclass of backbone.

var sampleView = Backbone.View.extend({

});

Like models and collections, we can also override the initialize and constructor of the backbone views. Lets try to see how we can override the initializefunction.

var sampleView = Backbone.View.extend({
    initialize: function() {
        console.log('sampleView has been created');
    }
});

Instantiating the view is also straight forward. A view can simply be instantiated using the newkeyword.

var view1 = new sampleView();

Associating model with a view

Every view will be backed by a model. This modelcan be passed to the view in the constructor.

var book1 = new Book({ ID: 1, BookName: "Book 1" });
var m_bookView = new bookView({model: book1});

This model can either be a backbone model or a backbone collection. The view can extract the information from its model and render the HTML accordingly.

Understanding the el property

Now we are saying that the views are responsible for listening to DOM element’s events and also for updating the DOM elements. For this to happen the view class should be associated/attached to a DOM element. Backbone views are always associated to a DOM element. This associated DOM element can be accessed/manipulated using the elproperty.

Now there are 2 ways to create view:

1.Creating a view that will get associated with an existing DOM element.
2.Creating a view that will create its own DOM element on the fly.

So lets start by looking at how we can create a view that will get associated with an existing DOM element. The views constructor is capable of accepting a lot of parameters. It can accept models, collections and even the DOM element that this view should associate itself to.

Lets say we want to create a view for an existing DOM element i.e. a div with id="sampleDiv".

var view1 = new sampleView({ el: $("#sampleDiv") });

When we run the application and try to watch the elproperty, we can see that the el property contains the div element.



Now lets see how we can create a view that will create a DOM element for it dynamically. The way it works is that we can specify tagName, className, id and attributes in a backbone view. Based on these values the el will be created by backbone. Lets try to create a simple div with id using this approach.

var sampleView2 = Backbone.View.extend({
    tagname: 'div',
    id: 'sampleDiv'
});

When we create this view, we can see that the view is associated with a div which was created using our specified tagName and id values.



Now these two approached provides a lot of flexibility while developing backbone applications. Let us try to look at a simple example to understand the complete picture. lets say we need to create a list of books. We know the area where these items should be rendered but we the actual items will be added at runtime. This can easily be achieved by creating an empty list and using JavaScript to add list items at runtime. Lets see how we can use backbone views to achieve this.

First let us create the a simple view that will render the book data as a list element. Do do this we will use the dynamically generated DOM element.

var bookView = Backbone.View.extend({
    tagname: "li",
    model: Book,
    render: function (){
        this.$el.html('<li>' + this.model.get("BookName") + '</li>');
        return this;
    }
});

What this view is doing is that, it is overiding the render function to render the book name in a list element. We have overridden the renderfunction to render the book as a list element.

Now we need a view that will contain this list elements i.e. the list view. For this lets create a simple list element on my HTML and then lets use this view class to use that el.

var bookListView = Backbone.View.extend({
    model: BooksCollection,

    render: function() {
        this.$el.html(); // lets render this view
        
        var self = this;

        for(var i = 0; i < this.model.length; ++i) {
            // lets create a book view to render
            var m_bookView = new bookView({model: this.model.at(i)});

            // lets add this book view to this list view
            this.$el.append(m_bookView.$el); 
            m_bookView.render(); // lets render the book           
        } 

         return this;
    },
});

What this view is doing is that, it is accepting a collection of books and in the render function it is using the bookViewto render the books inside the associated el. Now the next thing we need to do is to associated the list created on the HTML page with this view as its el and pass the books collection to this view as model.

var book1 = new Book({ ID: 1, BookName: "Book 1" });
var book2 = new Book({ ID: 2, BookName: "Book 2" });
var book3 = new Book({ ID: 3, BookName: "Book 3" });
var book4 = new Book({ ID: 4, BookName: "Book 4" });
var book5 = new Book({ ID: 5, BookName: "Book 5" });
var bookCollection = new BooksCollection([book1, book2, book3, book4, book5]);
var bookList = null;

$(document).ready(function () {
    bookList = new bookListView({ el: $("#bookList"), model: bookCollection });
    bookList.render();
});

Calling the render function of this view will use our backbone views and render the list of books in an unordered list.



Note: A view’s elcan be changed anytime by calling the setElementmethod of the view.

Using templates

Now in our example we have overridden the render function of our views and took charge of rendering the HTML is our own code. This is still better than plain JavaScript/jquery based approach because here our JavaScript code is not intermingled with HTML and there is a logical structure to our views.

But the problem is that our view HTML could become very complex and it might always not be possible to spit out that HTML from our render functions. To ease this problem backbone supports view templates. Any template engine can be used with backbone view. To understand the concept of templates, let us use the simple JavaScript style templates.

Lets say that every book needs to be rendered as a drop down menu. This can be achived by using bootstrap very easily. But creating all that HTML in the render function might not be a very good idea. So let us create one more set of views that will use the template to render the books in a drop-down.

var bookView2 = Backbone.View.extend({
   
    model: Book,
    tagName: 'li',
    template: '',

    initialize: function() {
        this.template = _.template($('#bookItem').html());
    },

    render: function() {
        this.$el.html(this.template(this.model.attributes));
        return this;
    }
});

var bookListView2 = Backbone.View.extend({
    model: BooksCollection,

    render: function() {
        this.$el.html(); // lets render this view
        
        for(var i = 0; i < this.model.length; ++i) {
            // lets create a book view to render
            var m_bookView = new bookView2({model: this.model.at(i)});

            // lets add this book view to this list view
            this.$el.append(m_bookView.$el); 
            m_bookView.render(); // lets render the book           
        } 

         return this;
    },
});

And the template is defined in the HTML file itself as:

 <script type="text/template" id="bookItem"> 
     <li role="presentation"><a role="menuitem" tabindex="-1" href="#"> <%= BookName %> </a></li>
    </script>




What will happen here is that the bookView2will use this template to render the books as list elements. Backbone can work on any view engine. Also the example taken here was little contrived but very complex templates can also be created and rendered using this approach very easily.

Listening to DOM events

Now there is one important thing remaining. how can a view object listen to DOM elements and perform needed actions. To understand this let us add a simple button on our list view and try to listen to its click action.

var bookView2 = Backbone.View.extend({
   
    model: Book,
    tagName: 'li',
    template: '',

    events: {
        'click': "itemClicked"
    },

    itemClicked: function () {
        alert('clicked: ' + this.model.get('BookName'));
    },

    initialize: function() {
        this.template = _.template($('#bookItem').html());
    },

    render: function() {
        this.$el.html(this.template(this.model.attributes));
        return this;
    }
});

Now whenever an a DOM element raises an event the associated view will look for its handler in the events section. If the handler exists, it calls that handler. this is very useful when we need to listen to DOM events and take some actions. we can use {"event selector": "callback"}format to declare our DOM event handlers. the selector are are usual jquery/css selectors.

Listening to Model changes

In large scale applications there might be multiple views rendering the same data. what if one view changes the data? should other views continue to show the stale data? Probably no. Thus we also need to listen to the model changes too. this can easily be achieved by listening to model changes as:

var bookListView = Backbone.View.extend({
    model: BooksCollection,

    initialize: function() {
        // lets listen to model change and update ourselves
        this.listenTo(this.model, "add", this.modelUpdated);
    },

    modelUpdated: function() {
        this.render();
    },
});

What we did here is that whenever new books are added to the collection. The associated view will be listening to the add event. On recieving this event it will simply renders the view again. This can be tested by simply adding few more books in the already rendering collection

function AddMoreBooks() {
    var i = bookCollection.length + 1;
    var newBook = new Book({ID: i, BookName: 'yet another book_' + i});

    bookCollection.add(newBook);
}




On same lines, we can also listen to change event to listen to model updates.

var bookView = Backbone.View.extend({
    tagName: "li",
    model: Book,

    initialize: function() {
        // lets listen to model change and update ourselves
        this.listenTo(this.model, "change", this.render);
    }
});

To test this, lets just try to update a book that is already being rendered on screen.


book1.set('BookName', book1.get('BookName') + '_updated');




Removing a view from DOM

Removing a view from DOM can be easily achieved by calling the remove function on the view.

bookList.remove();

Point of interest

In this article we looked at the backbone views. We looked at how we can use backbone views to implement better structured applications that can easily perform DOM manipulations.

原文链接:http://rahulrajatsingh.com/2014/07/backbone-tutorial-part-6-understanding-backbone-js-views/
分享到:
评论

相关推荐

    TODO-APP:使用Backbone.js开发ud989的项目

    Backbone.js 是一个轻量级的JavaScript库,它为Web应用提供了模型-视图-控制器(MVC)架构模式。在"TODO-APP: 使用Backbone.js开发ud989的项目"中,我们将深入探讨如何利用Backbone.js构建一个待办事项应用。 **一...

    singool:基于Backbone.js的框架,用于开发单页Web应用程序

    Backbone.js是一个JavaScript库,它提供了模型-视图-控制器(MVC)架构模式,帮助开发者组织代码,使得前端开发更加有序和高效。它强调数据模型和视图的绑定,以及事件驱动的编程方式。 Singool.js框架在其基础上...

    Backbone.js开发秘笈源码

    Backbone.js 是一个轻量级的JavaScript库,主要用于构建可维护性和结构化的Web应用。它提供了一套模型-视图-控制器(MVC)架构,帮助开发者组织代码,使得前端开发更加有序。在深入探讨Backbone.js的开发秘笈源码...

    Backbone.js(1.1.2) API中文文档.zip Backbone.js离线文档

    Backbone.js是一款轻量级的JavaScript库,专为构建丰富的Web应用程序而设计。它通过提供模型(Models)、视图(Views)、集合(Collections)和路由器(Routers)等核心概念,帮助开发者组织代码并实现MVC(Model-...

    BACKBONE.JS应用程序开发

    backbone.js提供了一套web开发的框架,为复杂javascript应用程序提供一个mvc结构。, 《backbone.js应用程序开发》详细介绍了如何使用backbone.js完成web应用开发。全书从了解mvc、spa和backbone.js的基本知识开始,...

    Backbone.js应用程序开发 中文清晰完整版pdf

    backbone.js提供了一套web开发的框架,为复杂javascript应用程序提供一个mvc结构。 《backbone.js应用程序开发》详细介绍了如何使用backbone.js完成web应用开发。全书从了解mvc、spa和backbone.js的基本知识开始,...

    Developing Backbone.js Applications

    Backbone.js是一个轻量级的JavaScript库,它为创建结构化的前端应用提供了模型-视图-控制器(MVC)架构。这个主题旨在帮助开发者深入理解和有效地运用Backbone.js来开发复杂而有组织的Web应用。 **Backbone.js核心...

    《Backbone.js实战》(陶国荣)源码

    Backbone.js是一款轻量级的JavaScript库,专为构建复杂的Web应用而设计。它通过提供模型、视图、集合和路由器等概念,帮助开发者更好地组织和管理代码,实现MVC(Model-View-Controller)模式在前端的落地。陶国荣的...

    Backbone.js的事件绑定

    Backbone.js是一个轻量级的JavaScript库,专为构建可维护和模块化的Web应用而设计。它基于MVC(Model-View-Controller)模式,帮助开发者组织和管理前端代码结构,使得复杂的应用程序更容易理解和扩展。在“Backbone...

    Backbone.js实战.zip

    Backbone.js是一款轻量级的JavaScript库,专为构建可维护性和结构化的Web应用而设计。它主要关注数据模型的管理、视图的渲染以及URL路由,为前端开发提供了强大的框架支持。本资源是关于"Backbone.js实战"的电子书,...

    前端项目-backbone.radio.zip

    1. **Backbone.js框架**:Backbone.js是一个轻量级的JavaScript库,它为构建单页应用(SPA)提供了模型-视图-视图模型(MVVM)的架构模式,帮助开发者组织代码结构。 2. **Backbone.Radio**:Backbone.Radio是...

    Pro Single Page Application Development - Using Backbone.Js and ASP.Net.2014

    Pro Single Page Application Development - Using Backbone.Js and ASP.Net by Gil Fink and Ido Flatow.2014

    BACKBONE.JS应用程序开发--高清版

    Backbone.js提供了一套Web开发的框架,为复杂的JavaScript应用程序提供了一个MVC结构。  《Backbone.js应用程序开发》详细介绍了如何使用Backbone.js完成Web应用开发。全书从了解MVC、SPA和Backbone.js的基本知识...

    backbone.js.zip

    Backbone.js是一个轻量级的JavaScript库,专为构建可维护和组织良好的前端应用程序而设计。这个库的核心理念是提供模型-视图-控制器(MVC)架构模式,帮助开发者在浏览器端更好地组织代码,提高代码复用性和可扩展性...

    用Backbone.js写的小项目

    Backbone.js是一款轻量级的JavaScript库,专为构建可维护性和结构化的Web应用程序而设计。它主要关注数据模型的管理、视图的渲染以及事件处理,为前端开发者提供了一套MVC(Model-View-Controller)架构模式的实现。...

    backbone.js underscore.js

    Backbone.js 和 Underscore.js 是两个在JavaScript开发中广泛使用的库,它们为构建复杂的Web应用程序提供了强大的工具。这两个库都是基于jQuery库,其中jQuery-1.10.2.js是jQuery的一个版本,它为DOM操作、事件处理...

Global site tag (gtag.js) - Google Analytics