Backbone入门指南(六):View (视图)

本文转自:http://yujianshenbing.iteye.com/

 

 

9. View (视图控制器)

  我们在前面的章节中介绍了Model和Collection,它们都是用于数据管理和交互,在本章我们讨论如何使用视图(View)将这些数据渲染到界面,以及如何管理界面事件和逻辑。

  Backbone中的视图提供了一组处理DOM事件、和渲染模型(或集合)数据的方法(在使用视图类之前,你必须先导入jQuery或Zepto)。

  视图类提供的方法非常简单,我们一般都会在Backbone.View的基础上进行扩展,但即使是特别复杂的视图类,它也应该仅仅是做界面事件、和渲染逻辑相关的操作,数据管理应该交由Model和Collection来完成,而业务逻辑应该由其它的类来完成。

9.1 定义和创建视图

  我们通过一段例子来说明如何创建View:

 

Js代码    收藏代码
  1. <div title="列表" style="color:red" id="list" class="listview"></div>  
  2. <script type="text/javascript">  
  3.     var ListView = Backbone.View.extend({  
  4.         el : '#list'  
  5.     });  
  6.     var listview = new ListView();  
  7. </script>  

 

 

  在这个例子中,我们定义了一个ListView视图类,它继承自Backbone.View,我们通过new关键字实例化一个ListView对象。

  在定义ListView时,我们设置了el属性,它应该是一个字符串形式的DOM选择器,但视图对象在实例化时,会在内部通过这个选择器获取对应的DOM对象,并重新存放在el属性中。因此我们可以在视图的内部通过this.el来访问所关联的DOM对象。

  每个视图对象都会关联一个DOM 对象,视图中所有操作都限定在这个DOM对象之内,这样做可以便于视图界面的控制(如渲染、隐藏和移除等),同时能提高查找视图内子元素的效率。

 

  上面的例子中,id为list的标签是我们事先准备好的,在定义ListView时可以直接通过#list选择器来引用它,但实际开发时这些DOM可能是动态生成的,至少在定义视图类时它们还不存在。此时,我们可以通过另一种方式来设置视图的DOM对象:

 

Js代码    收藏代码
  1. <script type="text/javascript">  
  2.     var ListView = Backbone.View.extend({  
  3.         tagName : 'div',  
  4.         className : 'listview',  
  5.         id : 'list',  
  6.         attributes : {  
  7.             title : '列表',  
  8.             style : 'color:red'  
  9.         },  
  10.         render : function() {  
  11.             this.el.innerHTML = 'Hello World!';  
  12.             document.body.appendChild(this.el);  
  13.         }  
  14.     });  
  15.     var listview = new ListView();  
  16.     listview.render();  
  17. </script>  

 

 

  运行这个例子,页面上输出了一段红色的文字:Hello World!。如果你通过Firebug等工具查看当前的DOM结构,你能看到</body>结束标签之前多了这样一段:

 

Html代码    收藏代码
  1. <div title="列表" style="color:red" id="list" class="listview">Hello World!</div>  

 

 

  这段标签是视图对象在实例化时根据tagName、className、id和attributes属性自动创建的,结合我们的代码,你可以很清晰地看出:

 

  • tagName表示新标签的名称(如果没有设置,则默认为div标签)
  • className对应标签的class样式属性
  • id对应标签的id属性

 

  这3个是最常见的HTML属性,你可以在定义视图类时直接设置它们,如果还需要设置更多的属性,可以通过attributes属性来定义。

  你可能注意到,我们还定义了一个render()方法,在创建ListView实例之后,我们调用该方法将新建的标签添加到页面尾部,否则它只会存储在el属性中,而不会被显示。

 

  上面介绍的两种创建方式,是在两种不同的场景中使用,分别是对已经存在的DOM创建视图,和创建视图时同时创建新的DOM,因此你不应该不会同时使用到它们。

9.2 处理DOM事件

  视图很重要的一个特性是帮助我们自动绑定界面事件。回想一下我们以前是如何为界面标签绑定事件的?可能就像这样:

 

Js代码    收藏代码
  1. <p>  
  2.     <input type="button" value="Create" id="create" />  
  3.     <input type="button" value="Read" id="read" />  
  4.     <input type="button" value="Update" id="update" />  
  5.     <input type="button" value="Delete" id="delete" />  
  6. </p>  
  7. <script type="text/javascript">  
  8.     function createData() {  
  9.         // todo  
  10.     }  
  11.     function readData() {  
  12.         // todo  
  13.     }  
  14.     function updateData() {  
  15.         // todo  
  16.     }  
  17.     function deleteData() {  
  18.         // todo  
  19.     }  
  20.   
  21.     $('#create').on('click', createData);  
  22.     $('#read').on('click', readData);  
  23.     $('#update').on('click', updateData);  
  24.     $('#delete').on('click', deleteData);  
  25. </script>  

 

 

  这是一个典型的通过jQuery绑定DOM事件的例子,如果你正在开发或曾经开发过一些复杂的应用,你可能尝试过通过某种方式将这些代码更好的组织起来,以便使它们看起来结构更加清晰,更易维护。

  Backbone的视图对象为我们提供了事件的自动绑定机制,用于更好地维护DOM和事件间的关系,来看看下面的例子:

 

Js代码    收藏代码
  1. <p id="view">  
  2.     <input type="button" value="Create" id="create" />  
  3.     <input type="button" value="Read" id="read" />  
  4.     <input type="button" value="Update" id="update" />  
  5.     <input type="button" value="Delete" id="delete" />  
  6. </p>  
  7. <script type="text/javascript">  
  8.     var MyView = Backbone.View.extend({  
  9.         el : '#view',  
  10.         events : {  
  11.             'click #create' : 'createData',  
  12.             'click #read' : 'readData',  
  13.             'click #update' : 'updateData',  
  14.             'click #delete' : 'deleteData'  
  15.         },  
  16.         createData : function() {  
  17.             // todo  
  18.         },  
  19.         readData : function() {  
  20.             // todo  
  21.         },  
  22.         updateData : function() {  
  23.             // todo  
  24.         },  
  25.         deleteData : function() {  
  26.             // todo  
  27.         }  
  28.     });  
  29.     var view = new MyView();  
  30. </script>  

 

 

  在这个例子中,我们将4个按钮放在一个id为view的标签中,并将这个标签与视图类MyView进行了关联。

  在定义视图类时,我们声明了一个events属性,它表示视图中的用户事件列表,描述方式如下:

  事件名称 选择器 : 事件处理函数

  事件名称可以是DOM对象支持的任何事件,选择器可以是jQuery或Zepto支持的任意选择器字符串(包括标签选择器、类选择器、id选择器等),而事件处理函数应该是已经定义在视图类本身的方法名称。

  视图对象会自动解析events列表中的描述,即使用jQuery或Zepto获取选择器描述的DOM对象,并将事件处理函数绑定到事件名称中。这些操作都会在视图类被实例化时自动完成,我们可以更关心视图类本身的结构,而不是刻意地去考虑如何绑定事件。

 

  你可能在担心另外一个问题:如果视图的DOM结构是动态生成的,Backbone是否提供了相应的方法用于动态绑定和解除事件?

  其实你并不需要关心这个问题,因为events中的事件是通过delegate()方法绑定到视图对象的el元素上,而并非是选择器所描述的元素。因此视图内的结构无论如何变化,events中的事件都是有效的。

  (如果你对jQuery比较熟悉,可能了解它所提供的delegate()方法。该方法实际上将事件绑定在父层元素,然后在事件冒泡过程中,通过检查目标子元素来触发事件。)

  视图对象通过delegate()方法绑定事件,意味着我们不需要关心视图结构变化对事件产生的影响,同时也说明events中选择器所对应的元素必须处于视图的el元素之内,否则绑定的事件是无法生效的。

 

  尽管如此,有些情况下可能我们仍然需要手动绑定和解除事件,视图对象提供了delegateEvents()和undelegateEvents()方法用于动态绑定和解除events事件列表,你可以通过查看API文档来了解它们。

9.3 渲染视图和数据

  我们之前提到,视图主要用于界面事件的绑定和数据渲染,然而视图对象仅仅提供了一个和渲染相关的方法render(),并且它是一个没有任何逻辑、也没有任何地方引用到的空方法,我们需要重载它来实现自己的渲染逻辑。

  视图中可能包含许多界面逻辑,这里建议所有的视图子类都重载render()方法,并将它作为最终渲染的入口方法。在团队开发中,严格按照规范编码可以帮助别人更好地理解和维护你的代码。

 

你可能感兴趣的:(JavaScript,mvc,html5,underscore,backbone)