Backbone.js教程(初级篇) 这是菜鸟与老油条,屌丝与高富帅的战争 —— 译者:茶几 @chajn 原作者:脱袜子·戴蕾丝 原文:http://backbonetutorials.com/

编程入门 行业动态 更新时间:2024-10-11 05:21:12

Backbone.js教程(初级篇) <a href=https://www.elefans.com/category/jswz/34/1770804.html style=这是菜鸟与老油条,屌丝与高富帅的战争 —— 译者:茶几 @chajn 原作者:脱袜子·戴蕾丝 原文:http://backbonetutorials.com/"/>

Backbone.js教程(初级篇) 这是菜鸟与老油条,屌丝与高富帅的战争 —— 译者:茶几 @chajn 原作者:脱袜子·戴蕾丝 原文:http://backbonetutorials.com/

Backbone.js教程(初级篇)

这是菜鸟与老油条,屌丝与高富帅的战争 —— 译者:茶几 @chajn

原作者:脱袜子·戴蕾丝  原文:/

1. 为啥你需要Backbone.js?

我们知道,仅仅使用jQuery或MooTools啥的来构建web应用或复杂的用户界面是极其困难的。
主要是因为这些JS库都把心思花费在它们擅长做的事情上了,而并没有意识到的是,即便没有任何页面结构,也是可以构建完整的应用的。
用Backbone就可以很容易的把你的应用部署到一个通过jQuery回调的嵌套堆中,然后在页面生成DOM元素实体。

我不需要解释为什么没有结构的页面构建是一个坏主意。
你当然可以每次构造应用的时候都发明一种实现方式,但这只是瞬间的美丽,你错过的是后世的精彩!
那你将永远只能是个屌ser。Balabala……

2. 啥是model?

网络上对MVC的定义是比较尿的,你甚至不知道怎样去理解和怎样去做。
但backbone.js的作者对backbone.js的model表现的定义就很明确。
Models是任何JS应用的核心部分,包括数据交互和众多相关逻辑:格式转换,校验,属性计算,访问控制等。
好的,让我们先创建一个model:

?
1 2 3 4 5 6 7 Person = Backbone.Model.extend({          initialize:  function (){              alert( "Welcome to this world" );          }      });           var  person =  new  Person;

-
SO我们看到new一个model的实例后就会触发initialize()函数(models,collections 和 views 的工作机制都是一样滴)。虽然可以不声明initialize,但我们可能会经常用到。

2.1 设置属性

现在我们想设置一些属性,有两种方式,可以在创建model实例时进行传参,也可以在实例生成后通过model.set(obj)来进行设置。  

?
01 02 03 04 05 06 07 08 09 10 11 Person = Backbone.Model.extend({          initialize:  function (){              alert( "Welcome to this world" );          }      });           var  person =  new  Person({ name:  "Thomas" , age: 67});      delete  person;      //或者用set,操作等价      var  person =  new  Person();      person.set({ name:  "Thomas" , age: 67});

-
两种方式在功能上是一样的。有设置属性,就有读取属性,下一步我们来获取它们。

2.2 获取属性

很简单,用 model.get(name)方法就可以读取属性值了。

?
01 02 03 04 05 06 07 08 09 10 11 Person = Backbone.Model.extend({          initialize:  function (){              alert( "欢迎来到这个二蛋的世界" );          }      });           var  person =  new  Person({ name:  "Thomas" , age: 67, children: [ 'Ryan' ]});           var  age = person.get( "age" );  // 67      var  name = person.get( "name" );  // "Thomas"      var  children = person.get( "children" );  // ['Ryan']

-

2.3 设置model默认属性

有的时候你可能会想让model有默认属性值。
没的问题,只要在进行model声明的时候设置个'defaults'就行了。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 Person = Backbone.Model.extend({          defaults: {              name:  'Fetus' ,              age: 0,              children: []          },          initialize:  function (){              alert( "欢迎来到这个三蛋的世界" );          }      });           var  person =  new  Person({ name:  "Thomas" , age: 67, children: [ 'Ryan' ]});           var  age = person.get( "age" );  // 67      var  name = person.get( "name" );  // "Thomas"      var  children = person.get( "children" );  // ['Ryan']

-

2.4 操纵model的属性

Models可以添加自定义方法来进行自身的属性修改,默认这些方法都是公开的。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 Person = Backbone.Model.extend({          defaults: {              name:  'Fetus' ,              age: 0,              children: []          },          initialize:  function (){              alert( "欢迎来到这个四蛋的世界" );          },          adopt:  function ( newChildsName ){              var  children_array =  this .get( "children" );              children_array.push( newChildsName );              this .set({ children: children_array });          }      });           var  person =  new  Person({ name:  "Thomas" , age: 67, children: [ 'Ryan' ]});      person.adopt( 'John Resig' );      var  children = person.get( "children" );  // ['Ryan', 'John Resig']

-
添加了自定义方法之后,我们就可以更好的控制实例的自身属性了。

2.5 监听model的属性改变

现在说点有用的,我们可以通过model.bind(event,callback)方法来绑定change事件来监听属性改变。
下面的这个例子就是在initialize方法中绑定了一个name属性改变的事件监听。
如果person的name属性改变了,就会弹出个对话框显示新值。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 Person = Backbone.Model.extend({          defaults: {              name:  'Fetus' ,              age: 0,              children: []          },          initialize:  function (){              alert( "欢迎来到这个无蛋的世界" );              this .bind( "change:name" function (){                  var  name =  this .get( "name" );  // 'Stewie Griffin'                  alert( "我的名字变为"  + name );              });          },          replaceNameAttr:  function ( name ){              this .set({ name: name });          }      });      var  person =  new  Person({ name:  "Thomas" , age: 67, children: [ 'Ryan' ]});      person.replaceNameAttr( 'Stewie Griffin' );  // 改变后触手会alert()

-
可以单个属性监听,也可以直接监听所有的属性,如:'this.bind("change", function(){});'

2.6 提取,存储和销毁

Models实际上是collection的一部分,用于向服务器请求啥的。
本部分的教程关注的是个体models,咳咳,更多的功能请查看collection部分。

2.7 提示和技巧

2.7.1 获取当前所有的属性

?
1 2 3 4 5 6 var  person =  new  Person({ name:  "Thomas" , age: 67, children: [ 'Ryan' ]});      var  attributes = person.toJSON();  // { name: "Thomas", age: 67, children: ['Ryan']}      /* 返回对当前属性的copy */      delete  attributes;      var  attributes = person.attributes;      /* 上行返回属性的直接引用,对其的任何改变就等于实例属性本身的改变,所以还是建议你使用.set()来进行属性的设置,因为还有backbone的监听呀 */

-

2.7.2 在设置或存储属性的时候进行数据校验

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Person = Backbone.Model.extend({          // 如果从validate中返回字符串了, Backbone就会抛个实例异常          validate:  function ( attributes ){              if ( attributes.age < 0 && attributes.name !=  "Dr Manhatten"  ){                  return  "你的存在是个错误" ;              }          },          initialize:  function (){              alert( "欢迎来到这个报错的世界" );              this .bind( "error" function (model, error){                  // 收到个错误,记录,警告,然后忘记它。╮(‵▽′)╭                  alert( error );              });          }      });           var  person =  new  Person;      person.set({ name:  "Mary Poppins" , age: -1 });      // 会触发error,输出警告      delete  person;           var  person =  new  Person;      person.set({ name:  "Dr Manhatten" , age: -1 }); // 上帝为何怜悯我们的灵魂,只因为打开的方式不对

-

3. 啥是view?

Backbone的views是用来体现应用的数据模型的。他们还可以用于监听事件。
本部分教程不会说关于views绑定models和collections的事情,重点说一下视图能力和如何使用views与JS模板库,特别是Underscore.js的 _.template。
我们使用jQuery 1.5操作DOM,当然也可以使用其他的库比如MooTools或Sizzle,但Backbone.js的官方文档说支持使用jQuery。
咳咳,也就是说Backbone.View事件在jQuery以外的库中可能无法使用。
好我们开始,这回我们要实现一个搜索框。

?
1 2 3 4 5 6 7 8 9 SearchView = Backbone.View.extend({          initialize:  function (){              alert( "Alerts suck." );          }      });           // The initialize function is always called when instantiating a Backbone View.      // Consider it the constructor of the class.      var  search_view =  new  SearchView;

-

3.1 “el”属性

“el”属性引用DOM对象。每个Backbone.js的view都会有个“el”属性。
如果没定义的话它会默认创建一个空的div元素。
来让我们设置个div#search_container到el属性上去,以保证这个Backbone.View是有效的。

?
01 02 03 04 05 06 07 08 09 10 11 < div  id = "search_container" ></ div >      < script  type = "text/javascript" >      SearchView = Backbone.View.extend({          initialize: function(){              alert("Alerts suck.");          }      });           var search_view = new SearchView({ el: $("#search_container") }); </ script >

-
注意:既然是绑定在了这个容器元素了,那就代表着所有的事件都是以此DOM元素为基础而触发的噢。

3.2 模板加载

Backbone.js是依赖于Underscore.js的,因为它包括micro-templating方案。
更多信息请参考Underscore.js'的官方文档去。
让我们实现一个“render()”方法进行视图初始化,“render()”方法会用jQuery加载我们的模板到“el”属性的容器中。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 < div  id = "search_container" ></ div >     < script  type = "text/template"  id = "search_template" >      < label >Search</ label >      < input  type = "text"  id = "search_input"  />      < input  type = "button"  id = "search_button"  value = "Search"  /> </ script >     < script  type = "text/javascript" >      SearchView = Backbone.View.extend({          initialize: function(){              this.render();          },          render: function(){              // Compile the template using underscore              var template = _.template( $("#search_template").html(), {} );              // Load the compiled HTML into the Backbone "el"              this.el.html( template );          }      });           var search_view = new SearchView({ el: $("#search_container") }); </ script >

-
提示:可以将你的模板放到CDN中的单独文件里,这样用户使用就不用每次都下载了。

3.3 事件监听

在view加一个监听,可以用Backbone.View的“events”属性。
要记得,事件监听只能绑定到“el”属性的子元素中。
让我们绑定个“click”事件到按钮上去。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 < div  id = "search_container" ></ div >     < script  type = "text/template"  id = "search_template" >      < label >Search</ label >      < input  type = "text"  id = "search_input"  />      < input  type = "button"  id = "search_button"  value = "Search"  /> </ script >     < script  type = "text/javascript" >      SearchView = Backbone.View.extend({          initialize: function(){              this.render();          },          render: function(){              var template = _.template( $("#search_template").html(), {} );              this.el.html( template );          },          events: {              "click input[type=button]": "doSearch"          },          doSearch: function( event ){              // Button clicked, you can access the element that was clicked with event.currentTarget              alert( "Search for " + $("#search_input").val() );          }      });           var search_view = new SearchView({ el: $("#search_container") }); </ script >

-

3.4 提示和技巧

3.4.1 使用模板变量

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 < div  id = "search_container" ></ div >     < script  type = "text/template"  id = "search_template" >      <!-- Access template variables with <%= %> -->      < label ><%= search_label %></ label >      < input  type = "text"  id = "search_input"  />      < input  type = "button"  id = "search_button"  value = "Search"  /> </ script >     < script  type = "text/javascript" >       SearchView = Backbone.View.extend({          initialize: function(){              this.render();          },          render: function(){              //Pass variables in using Underscore.js Template              var variables = { search_label: "My Search" };              // Compile the template using underscore              var template = _.template( $("#search_template").html(), variables );              // Load the compiled HTML into the Backbone "el"              this.el.html( template );          },          events: {              "click input[type=button]": "doSearch"          },          doSearch: function( event ){              // Button clicked, you can access the element that was clicked with event.currentTarget              alert( "Search for " + $("#search_input").val() );          }      });           var search_view = new SearchView({ el: $("#search_container") }); </ script >

-

4. 啥是collection?

Backbone的collections其实就是个有序的models集合。适用于以下情况;

  • Model: Student, Collection: ClassStudents

  • Model: Todo Item, Collection: Todo List

  • Model: Animals, Collection: Zoo

通常你的collection可能只用一个类型的model,但是models并不局限于某一类型的collection;

  • Model: Student, Collection: Gym Class

  • Model: Student, Collection: Art Class

  • Model: Student, Collection: English Class

关于Model/Collection,这里有一个通用的例子。

?
1 2 3 4 5 6 7 8 9 var  Song = Backbone.Model.extend({          initialize:  function (){              console.log( "Music is the answer" );          }      });           var  Album = Backbone.Collection.extend({          model: Song      });

-

4.1 构建 collection

现在我们来点实在的,下面的例子演示了collection的使用方法。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 var  Song = Backbone.Model.extend({          defaults: {              name:  "Not specified" ,              artist:  "Not specified"          },          initialize:  function (){              console.log( "Music is the answer" );          }      });           var  Album = Backbone.Collection.extend({          model: Song      });           var  song1 =  new  Song({ name:  "How Bizarre" , artist:  "OMC"  });      var  song2 =  new  Song({ name:  "Sexual Healing" , artist:  "Marvin Gaye" });      var  song3 =  new  Song({ name:  "Talk It Over In Bed" , artist:  "OMC"  });           var  myAlbum =  new  Album([ song1, song2, song3]);      console.log( myAlbum.models );  // [song1, song2, song3]

-

5. 啥是router?

?
1 2 3 4 5 //@注1:本章的所有实例都是在。 //如果是.html的形式,则路径标记#前不能加/。 //如:://example/test/test.html#/user/help //@注2:Backbone.js 0.9.2 的取路径后的值是posts/12,匹配^/posts/([^/]+)$不能(/posts/:id转换后的正则表达式)。所以原参数要改为posts/:id,测试才能通过。 //以下有错误的地方标红不改,以此类推。

-
Backbone的routers其实就相当于你的应用URL的hash(#)。
如果你读过“啥是view?”,那你应该知道,他们并不符合传统的MVC语义,本章将会详细解释这一点。
尽管Backbone的“router”对任何程序和功能都很有用,但它需要URL的routing/history功能。
Routers的定义包括路径和映射函数,下面的例子就让我们定义一个路径。
还请注意,routes只解析url的“#”之后的标记。
你的应用的所有链接都应该是像“#/action”或“#action”这样。
(附加个斜杠看起来会更好一些,比如:)

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 <script>      var  AppRouter = Backbone.Router.extend({          routes: {              "*actions" "defaultRoute"  // matches          },          defaultRoute:  function ( actions ){              // The variable passed in matches the variable in the route definition "actions"              alert( actions );          }      });      // Initiate the router      var  app_router =  new  AppRouter;      // Start Backbone history a neccesary step for bookmarkable URL's      Backbone.history.start();      </script>      _URL进行变化_ [Activate route]( #action) [Activate another route]( #/route/action)

-
请注意:Backbone 0.5 (released 1. July 2011)之前的版本,Router被称作Controller。为了避免字义混淆,Backbone的开发人员把名字改成Router了。
因此,如果你发现自己使用了Backbone的一个旧版本,那你应该写Backbone.Controller.extend({ ** });

5.1 动态Routing

原始框架允许你的routes定义包含动静混合态路径参数。
例如,你可能想进行检索一个post的id,你的URL看起来可能会是“”。
一旦这个路径被激活,你就可以取到id的值并做相应的处理了。下面是这个例子的实现。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <script>      var  AppRouter = Backbone.Router.extend({          routes: {              "/posts/:id" "getPost" , //@注2              "*actions" "defaultRoute"  // Backbone will try match the route above first          },          getPost:  function ( id ) {              // Note the variable in the route definition being passed in here              alert(  "Get post number "  + id );          },          defaultRoute:  function ( actions ){              alert( actions );          }      });      // Instantiate the router      var  app_router =  new  AppRouter;      // Start Backbone history a neccesary step for bookmarkable URL's      Backbone.history.start();      </script>      _URL进行改变_ [Post 120]( #/posts/120) [Post 130]( #/posts/130)

-

5.2 动态路径对比——":params"和"*splats"

Backbone使用两种参数模式实现路径,第一种是":params"匹配URL路径内任何斜杠之间的字符串,而还有一种是"splats"匹配任意数量的URL路径。
注意"splat"的本质意思,他总是最后一个变量,因为它匹配的是URL路径之后的全部内容。
在route中定义的任何"*splats"或":params"都会以参数的形式穿入关联函数中。
比如一个route定义了"/:route/:action",那就会传入两个参数(“route”和“action”) 到回调函数中。
下面的示例使用":params"和"*splats"。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 routes: {              "/posts/:id" "getPost" , //@注2,下同              // <a href="">Example</a>              "/download/*path" "downloadFile" ,              // <a href=".gif">Download</a>              "/:route/:action" "loadView" ,              // <a href="">LoadRoute/Action View</a>          },               getPost:  function ( id ){              alert(id);  // 121          },          downloadFile:  function ( path ){              alert(path);  // user/images/hey.gif          },          loadView:  function ( route, action ){              alert(route +  "_"  + action);  // dashboard_graph          }

-

这是菜鸟与老油条,屌丝与高富帅的战争 —— 译者:茶几 @chajn

原作者:脱袜子·戴蕾丝  原文:/

1. 为啥你需要Backbone.js?

我们知道,仅仅使用jQuery或MooTools啥的来构建web应用或复杂的用户界面是极其困难的。
主要是因为这些JS库都把心思花费在它们擅长做的事情上了,而并没有意识到的是,即便没有任何页面结构,也是可以构建完整的应用的。
用Backbone就可以很容易的把你的应用部署到一个通过jQuery回调的嵌套堆中,然后在页面生成DOM元素实体。

我不需要解释为什么没有结构的页面构建是一个坏主意。
你当然可以每次构造应用的时候都发明一种实现方式,但这只是瞬间的美丽,你错过的是后世的精彩!
那你将永远只能是个屌ser。Balabala……

2. 啥是model?

网络上对MVC的定义是比较尿的,你甚至不知道怎样去理解和怎样去做。
但backbone.js的作者对backbone.js的model表现的定义就很明确。
Models是任何JS应用的核心部分,包括数据交互和众多相关逻辑:格式转换,校验,属性计算,访问控制等。
好的,让我们先创建一个model:

?
1 2 3 4 5 6 7 Person = Backbone.Model.extend({          initialize:  function (){              alert( "Welcome to this world" );          }      });           var  person =  new  Person;

-
SO我们看到new一个model的实例后就会触发initialize()函数(models,collections 和 views 的工作机制都是一样滴)。虽然可以不声明initialize,但我们可能会经常用到。

2.1 设置属性

现在我们想设置一些属性,有两种方式,可以在创建model实例时进行传参,也可以在实例生成后通过model.set(obj)来进行设置。  

?
01 02 03 04 05 06 07 08 09 10 11 Person = Backbone.Model.extend({          initialize:  function (){              alert( "Welcome to this world" );          }      });           var  person =  new  Person({ name:  "Thomas" , age: 67});      delete  person;      //或者用set,操作等价      var  person =  new  Person();      person.set({ name:  "Thomas" , age: 67});

-
两种方式在功能上是一样的。有设置属性,就有读取属性,下一步我们来获取它们。

2.2 获取属性

很简单,用 model.get(name)方法就可以读取属性值了。

?
01 02 03 04 05 06 07 08 09 10 11 Person = Backbone.Model.extend({          initialize:  function (){              alert( "欢迎来到这个二蛋的世界" );          }      });           var  person =  new  Person({ name:  "Thomas" , age: 67, children: [ 'Ryan' ]});           var  age = person.get( "age" );  // 67      var  name = person.get( "name" );  // "Thomas"      var  children = person.get( "children" );  // ['Ryan']

-

2.3 设置model默认属性

有的时候你可能会想让model有默认属性值。
没的问题,只要在进行model声明的时候设置个'defaults'就行了。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 Person = Backbone.Model.extend({          defaults: {              name:  'Fetus' ,              age: 0,              children: []          },          initialize:  function (){              alert( "欢迎来到这个三蛋的世界" );          }      });           var  person =  new  Person({ name:  "Thomas" , age: 67, children: [ 'Ryan' ]});           var  age = person.get( "age" );  // 67      var  name = person.get( "name" );  // "Thomas"      var  children = person.get( "children" );  // ['Ryan']

-

2.4 操纵model的属性

Models可以添加自定义方法来进行自身的属性修改,默认这些方法都是公开的。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 Person = Backbone.Model.extend({          defaults: {              name:  'Fetus' ,              age: 0,              children: []          },          initialize:  function (){              alert( "欢迎来到这个四蛋的世界" );          },          adopt:  function ( newChildsName ){              var  children_array =  this .get( "children" );              children_array.push( newChildsName );              this .set({ children: children_array });          }      });           var  person =  new  Person({ name:  "Thomas" , age: 67, children: [ 'Ryan' ]});      person.adopt( 'John Resig' );      var  children = person.get( "children" );  // ['Ryan', 'John Resig']

-
添加了自定义方法之后,我们就可以更好的控制实例的自身属性了。

2.5 监听model的属性改变

现在说点有用的,我们可以通过model.bind(event,callback)方法来绑定change事件来监听属性改变。
下面的这个例子就是在initialize方法中绑定了一个name属性改变的事件监听。
如果person的name属性改变了,就会弹出个对话框显示新值。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 Person = Backbone.Model.extend({          defaults: {              name:  'Fetus' ,              age: 0,              children: []          },          initialize:  function (){              alert( "欢迎来到这个无蛋的世界" );              this .bind( "change:name" function (){                  var  name =  this .get( "name" );  // 'Stewie Griffin'                  alert( "我的名字变为"  + name );              });          },          replaceNameAttr:  function ( name ){              this .set({ name: name });          }      });      var  person =  new  Person({ name:  "Thomas" , age: 67, children: [ 'Ryan' ]});      person.replaceNameAttr( 'Stewie Griffin' );  // 改变后触手会alert()

-
可以单个属性监听,也可以直接监听所有的属性,如:'this.bind("change", function(){});'

2.6 提取,存储和销毁

Models实际上是collection的一部分,用于向服务器请求啥的。
本部分的教程关注的是个体models,咳咳,更多的功能请查看collection部分。

2.7 提示和技巧

2.7.1 获取当前所有的属性

?
1 2 3 4 5 6 var  person =  new  Person({ name:  "Thomas" , age: 67, children: [ 'Ryan' ]});      var  attributes = person.toJSON();  // { name: "Thomas", age: 67, children: ['Ryan']}      /* 返回对当前属性的copy */      delete  attributes;      var  attributes = person.attributes;      /* 上行返回属性的直接引用,对其的任何改变就等于实例属性本身的改变,所以还是建议你使用.set()来进行属性的设置,因为还有backbone的监听呀 */

-

2.7.2 在设置或存储属性的时候进行数据校验

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 Person = Backbone.Model.extend({          // 如果从validate中返回字符串了, Backbone就会抛个实例异常          validate:  function ( attributes ){              if ( attributes.age < 0 && attributes.name !=  "Dr Manhatten"  ){                  return  "你的存在是个错误" ;              }          },          initialize:  function (){              alert( "欢迎来到这个报错的世界" );              this .bind( "error" function (model, error){                  // 收到个错误,记录,警告,然后忘记它。╮(‵▽′)╭                  alert( error );              });          }      });           var  person =  new  Person;      person.set({ name:  "Mary Poppins" , age: -1 });      // 会触发error,输出警告      delete  person;           var  person =  new  Person;      person.set({ name:  "Dr Manhatten" , age: -1 }); // 上帝为何怜悯我们的灵魂,只因为打开的方式不对

-

3. 啥是view?

Backbone的views是用来体现应用的数据模型的。他们还可以用于监听事件。
本部分教程不会说关于views绑定models和collections的事情,重点说一下视图能力和如何使用views与JS模板库,特别是Underscore.js的 _.template。
我们使用jQuery 1.5操作DOM,当然也可以使用其他的库比如MooTools或Sizzle,但Backbone.js的官方文档说支持使用jQuery。
咳咳,也就是说Backbone.View事件在jQuery以外的库中可能无法使用。
好我们开始,这回我们要实现一个搜索框。

?
1 2 3 4 5 6 7 8 9 SearchView = Backbone.View.extend({          initialize:  function (){              alert( "Alerts suck." );          }      });           // The initialize function is always called when instantiating a Backbone View.      // Consider it the constructor of the class.      var  search_view =  new  SearchView;

-

3.1 “el”属性

“el”属性引用DOM对象。每个Backbone.js的view都会有个“el”属性。
如果没定义的话它会默认创建一个空的div元素。
来让我们设置个div#search_container到el属性上去,以保证这个Backbone.View是有效的。

?
01 02 03 04 05 06 07 08 09 10 11 < div  id = "search_container" ></ div >      < script  type = "text/javascript" >      SearchView = Backbone.View.extend({          initialize: function(){              alert("Alerts suck.");          }      });           var search_view = new SearchView({ el: $("#search_container") }); </ script >

-
注意:既然是绑定在了这个容器元素了,那就代表着所有的事件都是以此DOM元素为基础而触发的噢。

3.2 模板加载

Backbone.js是依赖于Underscore.js的,因为它包括micro-templating方案。
更多信息请参考Underscore.js'的官方文档去。
让我们实现一个“render()”方法进行视图初始化,“render()”方法会用jQuery加载我们的模板到“el”属性的容器中。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 < div  id = "search_container" ></ div >     < script  type = "text/template"  id = "search_template" >      < label >Search</ label >      < input  type = "text"  id = "search_input"  />      < input  type = "button"  id = "search_button"  value = "Search"  /> </ script >     < script  type = "text/javascript" >      SearchView = Backbone.View.extend({          initialize: function(){              this.render();          },          render: function(){              // Compile the template using underscore              var template = _.template( $("#search_template").html(), {} );              // Load the compiled HTML into the Backbone "el"              this.el.html( template );          }      });           var search_view = new SearchView({ el: $("#search_container") }); </ script >

-
提示:可以将你的模板放到CDN中的单独文件里,这样用户使用就不用每次都下载了。

3.3 事件监听

在view加一个监听,可以用Backbone.View的“events”属性。
要记得,事件监听只能绑定到“el”属性的子元素中。
让我们绑定个“click”事件到按钮上去。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 < div  id = "search_container" ></ div >     < script  type = "text/template"  id = "search_template" >      < label >Search</ label >      < input  type = "text"  id = "search_input"  />      < input  type = "button"  id = "search_button"  value = "Search"  /> </ script >     < script  type = "text/javascript" >      SearchView = Backbone.View.extend({          initialize: function(){              this.render();          },          render: function(){              var template = _.template( $("#search_template").html(), {} );              this.el.html( template );          },          events: {              "click input[type=button]": "doSearch"          },          doSearch: function( event ){              // Button clicked, you can access the element that was clicked with event.currentTarget              alert( "Search for " + $("#search_input").val() );          }      });           var search_view = new SearchView({ el: $("#search_container") }); </ script >

-

3.4 提示和技巧

3.4.1 使用模板变量

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 < div  id = "search_container" ></ div >     < script  type = "text/template"  id = "search_template" >      <!-- Access template variables with <%= %> -->      < label ><%= search_label %></ label >      < input  type = "text"  id = "search_input"  />      < input  type = "button"  id = "search_button"  value = "Search"  /> </ script >     < script  type = "text/javascript" >       SearchView = Backbone.View.extend({          initialize: function(){              this.render();          },          render: function(){              //Pass variables in using Underscore.js Template              var variables = { search_label: "My Search" };              // Compile the template using underscore              var template = _.template( $("#search_template").html(), variables );              // Load the compiled HTML into the Backbone "el"              this.el.html( template );          },          events: {              "click input[type=button]": "doSearch"          },          doSearch: function( event ){              // Button clicked, you can access the element that was clicked with event.currentTarget              alert( "Search for " + $("#search_input").val() );          }      });           var search_view = new SearchView({ el: $("#search_container") }); </ script >

-

4. 啥是collection?

Backbone的collections其实就是个有序的models集合。适用于以下情况;

  • Model: Student, Collection: ClassStudents

  • Model: Todo Item, Collection: Todo List

  • Model: Animals, Collection: Zoo

通常你的collection可能只用一个类型的model,但是models并不局限于某一类型的collection;

  • Model: Student, Collection: Gym Class

  • Model: Student, Collection: Art Class

  • Model: Student, Collection: English Class

关于Model/Collection,这里有一个通用的例子。

?
1 2 3 4 5 6 7 8 9 var  Song = Backbone.Model.extend({          initialize:  function (){              console.log( "Music is the answer" );          }      });           var  Album = Backbone.Collection.extend({          model: Song      });

-

4.1 构建 collection

现在我们来点实在的,下面的例子演示了collection的使用方法。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 var  Song = Backbone.Model.extend({          defaults: {              name:  "Not specified" ,              artist:  "Not specified"          },          initialize:  function (){              console.log( "Music is the answer" );          }      });           var  Album = Backbone.Collection.extend({          model: Song      });           var  song1 =  new  Song({ name:  "How Bizarre" , artist:  "OMC"  });      var  song2 =  new  Song({ name:  "Sexual Healing" , artist:  "Marvin Gaye" });      var  song3 =  new  Song({ name:  "Talk It Over In Bed" , artist:  "OMC"  });           var  myAlbum =  new  Album([ song1, song2, song3]);      console.log( myAlbum.models );  // [song1, song2, song3]

-

5. 啥是router?

?
1 2 3 4 5 //@注1:本章的所有实例都是在。 //如果是.html的形式,则路径标记#前不能加/。 //如:://example/test/test.html#/user/help //@注2:Backbone.js 0.9.2 的取路径后的值是posts/12,匹配^/posts/([^/]+)$不能(/posts/:id转换后的正则表达式)。所以原参数要改为posts/:id,测试才能通过。 //以下有错误的地方标红不改,以此类推。

-
Backbone的routers其实就相当于你的应用URL的hash(#)。
如果你读过“啥是view?”,那你应该知道,他们并不符合传统的MVC语义,本章将会详细解释这一点。
尽管Backbone的“router”对任何程序和功能都很有用,但它需要URL的routing/history功能。
Routers的定义包括路径和映射函数,下面的例子就让我们定义一个路径。
还请注意,routes只解析url的“#”之后的标记。
你的应用的所有链接都应该是像“#/action”或“#action”这样。
(附加个斜杠看起来会更好一些,比如:)

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 <script>      var  AppRouter = Backbone.Router.extend({          routes: {              "*actions" "defaultRoute"  // matches          },          defaultRoute:  function ( actions ){              // The variable passed in matches the variable in the route definition "actions"              alert( actions );          }      });      // Initiate the router      var  app_router =  new  AppRouter;      // Start Backbone history a neccesary step for bookmarkable URL's      Backbone.history.start();      </script>      _URL进行变化_ [Activate route]( #action) [Activate another route]( #/route/action)

-
请注意:Backbone 0.5 (released 1. July 2011)之前的版本,Router被称作Controller。为了避免字义混淆,Backbone的开发人员把名字改成Router了。
因此,如果你发现自己使用了Backbone的一个旧版本,那你应该写Backbone.Controller.extend({ ** });

5.1 动态Routing

原始框架允许你的routes定义包含动静混合态路径参数。
例如,你可能想进行检索一个post的id,你的URL看起来可能会是“”。
一旦这个路径被激活,你就可以取到id的值并做相应的处理了。下面是这个例子的实现。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 <script>      var  AppRouter = Backbone.Router.extend({          routes: {              "/posts/:id" "getPost" , //@注2              "*actions" "defaultRoute"  // Backbone will try match the route above first          },          getPost:  function ( id ) {              // Note the variable in the route definition being passed in here              alert(  "Get post number "  + id );          },          defaultRoute:  function ( actions ){              alert( actions );          }      });      // Instantiate the router      var  app_router =  new  AppRouter;      // Start Backbone history a neccesary step for bookmarkable URL's      Backbone.history.start();      </script>      _URL进行改变_ [Post 120]( #/posts/120) [Post 130]( #/posts/130)

-

5.2 动态路径对比——":params"和"*splats"

Backbone使用两种参数模式实现路径,第一种是":params"匹配URL路径内任何斜杠之间的字符串,而还有一种是"splats"匹配任意数量的URL路径。
注意"splat"的本质意思,他总是最后一个变量,因为它匹配的是URL路径之后的全部内容。
在route中定义的任何"*splats"或":params"都会以参数的形式穿入关联函数中。
比如一个route定义了"/:route/:action",那就会传入两个参数(“route”和“action”) 到回调函数中。
下面的示例使用":params"和"*splats"。

?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 routes: {              "/posts/:id" "getPost" , //@注2,下同              // <a href="">Example</a>              "/download/*path" "downloadFile" ,              // <a href=".gif">Download</a>              "/:route/:action" "loadView" ,              // <a href="">LoadRoute/Action View</a>          },               getPost:  function ( id ){              alert(id);  // 121          },          downloadFile:  function ( path ){              alert(path);  // user/images/hey.gif          },          loadView:  function ( route, action ){              alert(route +  "_"  + action);  // dashboard_graph          }

-

更多推荐

Backbone.js教程(初级篇) 这是菜鸟与老油条,屌丝与高富帅的战争 —— 译者:茶几 @chajn 原作者:脱袜子·戴蕾丝 原文:http://ba

本文发布于:2024-03-12 10:31:32,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1731313.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:这是   菜鸟   老油条   茶几   译者

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!