Backbone,英文意思是:勇气, 脊骨,可是在程序里面,尤为是在Backbone后面加上后缀js以后,它就变成了一个框架,一个js库。javascript
Backbone.js,不知道做者是以什么样的目的来对其命名的,多是但愿这个库会成为web端开发中脊梁骨。html
好了,八卦完了开始正题。前端
Backbone.js提供了一套web开发的框架,经过Models进行key-value绑定及自定义事件处理,经过Collections提供一套丰富的API用于枚举功能,经过Views来进行事件处理及与现有的Application经过RESTful JSON接口进行交互.它是基于jQuery和underscore的一个前端js框架。java
总体上来讲,Backbone.js是一个web端javascript的MVC框架,算是轻量级的框架。它能让你像写Java(后端)代码组织js代码,定义类,类的属性以及方法。更重要的是它可以优雅的把本来无逻辑的javascript代码进行组织,而且提供数据和逻辑相互分离的方法,减小代码开发过程当中的数据和逻辑混乱。python
在Backbonejs有几个重要的概念,先介绍一下:Model,Collection,View,Router。其中Model是根据现实数据创建的抽象,好比人(People);Collection是Model的一个集合,好比一群人;View是对Model和Collection中数据的展现,把数据渲染(Render)到页面上;Router是对路由的处理,就像传统网站经过url现实不一样的页面,在单页面应用(SPA)中经过Router来控制前面说的View的展现。jquery
经过Backbone,你能够把你的数据看成Models,经过Models你能够建立数据,进行数据验证,销毁或者保存到服务器上。当界面上的操做引发model中属性的变化时,model会触发change的事件。那些用来显示model状态的views会接受到model触发change的消息,进而发出对应的响应,而且从新渲染新的数据到界面。在一个完整的Backbone应用中,你不须要写那些胶水代码来从DOM中经过特殊的id来获取节点,或者手工的更新HTML页面,由于在model发生变化时,views会很简单的进行自我更新。git
上面是一个简单的介绍,关于backbone我看完他的介绍和简单的教程以后,第一印象是它为前端开发制定了一套本身的规则,在这个规则下,咱们能够像使用django组织python代码同样的组织js代码,它很优雅,可以使前端和server的交互变得简单。github
在查backbone资料的时候,发现没有很系统的中文入门资料和更多的实例,因此我打算本身边学边实践边写,争取能让你们经过一系列文章能快速的用上Backbone.js。web
关于backbone的更多介绍参看这个:数据库
http://documentcloud.github.com/backbone/
它虽然是轻量级框架,可是框架这东西也不是随便什么地方都能用的,否则就会出现杀鸡用牛刀,费力不讨好的结果。那么适用在哪些地方呢?
根据个人理解,以及Backbone的功能,若是单个网页上有很是复杂的业务逻辑,那么用它很合适,它能够很容易的操做DOM和组织js代码。
豆瓣的阿尔法城是一个极好的例子——纯单页、复杂的前端逻辑。
固然,除了我本身分析的应用范围以外,在Backbone的文档上看到了不少使用它的外国站点,有不少,说明Backbonejs仍是很易用的。
稍稍列一下国内用到Backbonejs的站点:
1. 豆瓣阿尔法城 连接:http://alphatown.com/
2. 豆瓣阅读 连接:http://read.douban.com/ 主要用在图书的正文页
3. 百度开发者中心 连接:http://developer.baidu.com/
4. 手机搜狐直播间 连接:http://zhibo.m.sohu.com/
5. OATOS企业网盘 连接:http://app.oatos.com
如今,咱们就要开始学习Backbonejs了,我假设你没有看过个人初版,那一版有不少不少问题,在博客上也有不少人反馈。可是若是你把那一版看明白了,这新版的教程你能够粗略的浏览一遍,不事后面新补充的实践是要本身写出来、跑起来的。
先说咱们为何要学习这新的东西呢?简单说来是为了掌握更加先进的工具。那为何要掌握先进的工具呢?简单来讲就是为了让咱们可以以更合理、优雅的方式完成工做,反应到代码上就是让代码变得可维护,易扩展。若是从复杂的方向来讲的话,这俩话题都够我写好几天的博客了。
学以至用,最直接有效的就是用起来,光学是没用的,尤为是编程这样的实践科学。新手最常犯的一个错误就是喜欢不停的去看书,看过了就觉得会了,而后就开始疯狂的学下一本。却不知看懂和写出来能运行是两种彻底不一样的状态。所以建议新手——编程新手仍是踏踏实实的把代码都敲了,执行了,成功了才是。
下面直接给一个简单的Demo出来,用到了Backbonejs的三个主要模块:Views,Collection,Model。经过执行这个例子,了解这个例子的运行过程,快速对要作的东西有一个感受,而后再逐步击破。
这个demo的主要功能是点击页面上得“新手报到”按钮,弹出对话框,输入内容以后,把内容拼上固定的字符串显示到页面上。事件触发的逻辑是: click 触发checkIn方法,而后checkIn构造World对象放到已经初始化worlds这个collection中。
来看完整的代码:
<!DOCTYPE html> <html> <head> <title>the5fire.com-backbone.js-Hello World</title> </head> <body> <button id="check">新手报到</button> <ul id="world-list"> </ul> <a href="http://www.the5fire.com">更多教程</a> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/jquery-1.10.2.js"></script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/underscore.js"></script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/backbone.js"></script> <script> (function ($) { World = Backbone.Model.extend({ //建立一个World的对象,拥有name属性 name: null }); Worlds = Backbone.Collection.extend({ //World对象的集合 initialize: function (models, options) { this.bind("add", options.view.addOneWorld); } }); AppView = Backbone.View.extend({ el: $("body"), initialize: function () { //构造函数,实例化一个World集合类 //而且以字典方式传入AppView的对象 this.worlds = new Worlds(null, { view : this }) }, events: { //事件绑定,绑定Dom中id为check的元素 "click #check": "checkIn", }, checkIn: function () { var world_name = prompt("请问,您是哪星人?"); if(world_name == "") world_name = '未知'; var world = new World({ name: world_name }); this.worlds.add(world); }, addOneWorld: function(model) { $("#world-list").append("<li>这里是来自 <b>" + model.get('name') + "</b> 星球的问候:hello world!</li>"); } }); //实例化AppView var appview = new AppView; })(jQuery); </script></body> </html>
这里面涉及到backbone的三个部分,View、Model、Collection,其中Model表明一个数据模型,Collection是模型的一个集合,而View是用来处理页面以及简单的页面逻辑的。
动手把代码放到你的编辑器中吧,成功执行,而后修改某个地方,再次尝试。
上一章主要是经过简单的代码对Backbonejs作了一个归纳的展现,这一章开始从Model层提及,详细解释Backbonejs中的Model这个东西。
对于Model这一部分,其官网是这么说的:“Model是js应用的核心,包括基础的数据以及围绕着这些数据的逻辑:数据转换、验证、属性计算和访问控制”。这句话基本上高度归纳了Model在一个项目中的做用。实际上,不只仅是js应用,在任何以数据收集和处理的项目中Model都是很重要的一块内容。
Model这个概念在个人印象中是来自于MVC这个东西,Model在其中的做用,除了是对业务中实体对象的抽象,另外的做用就是作持久化,所谓持久化就是把数据存储到磁盘上——文件形式、数据库形式。在web端也有对应的操做,好比存入LocalStorage,或者Cookie。
在web端,Model还有一个重要的功能就是和服务器端进行数据交互,就像是服务器端的程序须要和数据库交互同样。所以Model应该是携带数据流窜于各个模块之间的东西。
下面让咱们经过一个一个的实例来逐步了解Model。
先定义一个页面结构,实践时须在注释的地方填上各小节的代码
<!DOCTYPE html> <html> <head> <title>the5fire-backbone-model</title> </head> <body> </body> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/jquery-1.10.2.js"></script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/underscore.js"></script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/backbone.js"></script><script>(function ($) { /** *此处填充代码下面练习代码 **/})(jQuery);</script></html>
var Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); } });var man = new Man;
这个确实很简单了,只是定义了一个最基础的Model,只是实现了initialize这个初始化方法,也称构造函数。这个函数会在Model被实例化时调用。
第一种,直接定义,设置默认值。
var Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); }, defaults: { name:'张三', age: '38' } });var man = new Man;alert(man.get('name'));
第二种,赋值时定义
var Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); } });var man = new Man; man.set({name:'the5fire',age:'10'});alert(man.get('name'));
从这个对象的取值方式能够知道,属性在一个Model是以字典(或者相似字典)的方式存在的,第一种设定默认值的方式,只不过是实现了Backbone的defaults这个方法,或者是给defaults进行了赋值。
var Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); }, defaults: { name:'张三', age: '38' }, aboutMe: function(){ return '我叫' + this.get('name') + ',今年' + this.get('age') + '岁'; } });var man = new Man;alert(man.aboutMe());
也是比较简单,只是增长了一个新的属性,值是一个function。说到这,不知道你是否发现,在全部的定义或者赋值操做中,都是经过字典的方式来完成的,好比extend Backbone的Model,以及定义方法,定义默认值。方法的调用和其余的语言同样,直接 .
便可,参数的定义和传递也同样。
假设你有在对象的某个属性发生变化时去处理一些业务的话,下面的示例会有帮助。依然是定义那个类,不一样的是咱们在构造函数中绑定了name属性的change事件。这样当name发生变化时,就会触发这个function。
var Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); //初始化时绑定监听 this.bind("change:name",function(){ var name = this.get("name"); alert("你改变了name属性为:" + name); }); }, defaults: { name:'张三', age: '38' }, aboutMe: function(){ return '我叫' + this.get('name') + ',今年' + this.get('age') + '岁'; } });var man = new Man;//触发绑定的change事件,alert。man.set({name:'the5fire'});//触发绑定的change事件,alert。man.set({name:'the5fire.com'});
var Man = Backbone.Model.extend({ initialize: function(){ alert('Hey, you create me!'); //初始化时绑定监听, change事件会先于validate发生 this.bind("change:name",function(){ var name = this.get("name"); alert("你改变了name属性为:" + name); }); this.bind("invalid",function(model,error){ alert(error); }); }, defaults: { name:'张三', age: '38' }, validate:function(attributes){ if(attributes.name == '') { return "name不能为空!"; } }, aboutMe: function(){ return '我叫' + this.get('name') + ',今年' + this.get('age') + '岁'; } });var man = new Man;// 这种方式添加错误处理也行// man.on('invalid', function(model, error){// alert(error);// });//默认set时不进行验证man.set({name:''});//手动触发验证, set时会触发//man.set({name:''}, {'validate':true});//save时触发验证。根据验证规则,弹出错误提示。man.save();
首先须要声明的是,这个例子须要后端配合,能够在 code 目录中找到对应的py文件,须要webpy和mako这两个库。 这里须要为对象定义一个url属性,调用save方法时会post对象的全部属性到server端,调用fetch方法是又会发送get请求到server端。接受数据和发送数据均为json格式:
var Man = Backbone.Model.extend({ url:'/man/', initialize: function(){ alert('Hey, you create me!'); //初始化时绑定监听 this.bind("change:name",function(){ var name = this.get("name"); alert("你改变了name属性为:" + name); }); this.bind("error",function(model,error){ alert(error); }); }, defaults: { name:'张三', age: '38' }, validate:function(attributes){ if(attributes.name == '') { return "name不能为空!"; } }, aboutMe: function(){ return '我叫' + this.get('name') + ',今年' + this.get('age') + '岁'; } });var man = new Man;; man.set({name:'the5fire'});//会发送POST到模型对应的url,数据格式为json{"name":"the5fire","age":38}man.save();//而后接着就是从服务器端获取数据使用方法fetch([options])var man1 = new Man;//第一种状况,若是直接使用fetch方法,//那么他会发送get请求到你model的url中,//你在服务器端能够经过判断是get仍是post来进行对应的操做。man1.fetch();//第二种状况,在fetch中加入参数,以下:man1.fetch({url:'/man/'});//这样,就会发送get请求到/getmans/这个url中,//服务器返回的结果样式应该是对应的json格式数据,同save时POST过去的格式。//不过接受服务器端返回的数据方法是这样的:man1.fetch({url:'/man/', success:function(model,response){ alert('success'); //model为获取到的数据 alert(model.get('name')); },error:function(){ //当返回格式不正确或者是非json数据时,会执行此方法 alert('error'); } });
还有一点值得一提的是关于url和urlRoot的事情了,若是你设置了url,那么你的CRUD都会发送对应请求到这个url上,可是这样有一个问题,就是delete请求,发送了请求,可是却没有发送任何数据,那么你在服务器端就不知道应该删除哪一个对象(记录),因此这里又一个urlRoot的概念,你设置了urlRoot以后,你发送PUT和DELETE请求的时候,其请求的url地址就是:/baseurl/[model.id],这样你就能够在服务器端经过对url后面值的提取更新或者删除对应的对象(记录)
补充一点,就是关于服务器的异步操做都是经过Backbone.sync这个方法来完成的,调用这个方法的时候会自动的传递一个参数过去,根据参数向服务器端发送对应的请求。好比你save,backbone会判断你的这个对象是否是新的,若是是新建立的则参数为create,若是是已存在的对象只是进行了改变,那么参数就为update,若是你调用fetch方法,那参数就是read,若是是destory,那么参数就是delete。也就是所谓的CRUD ("create", "read", "update", or "delete"),而这四种参数对应的请求类型为POST,GET,PUT,DELETE。你能够在服务器根据这个request类型,来作出相应的CRUD操做。
关于Backbone.sync在后面会有如何自定义这一部分的章节。
上面服务器端的代码在 code
下能够找到,基于webpy和mako的。
上一节介绍了model的使用,model算是对现实中某一物体的抽象,好比你能够定义一本书的model,具备书名(title)还有书页(page_num)等属性。仅仅用一个Model是不足以呈现现实世界的内容,所以基于Model,这节咱们来看collection。collection是model对象的一个有序的集合,也能够理解为是model的容器。概念理解起来十分简单,在经过几个例子来看一下,会以为更容易理解。
var Book = Backbone.Model.extend({ defaults : { title:'default' }, initialize: function(){ //alert('Hey, you create me!'); } });var BookShelf = Backbone.Collection.extend({ model : Book });var book1 = new Book({title : 'book1'});var book2 = new Book({title : 'book2'});var book3 = new Book({title : 'book3'});//注意这里面是数组,或者使用add//var bookShelf = new BookShelf([book1, book2, book3]);var bookShelf = new BookShelf; bookShelf.add(book1); bookShelf.add(book2); bookShelf.add(book3); bookShelf.remove(book3);//基于underscore这个js库,还可使用each的方法获取collection中的数据bookShelf.each(function(book){ alert(book.get('title')); });
很容易理解吧。
首先要在上面的的Bookshelf中定义url,注意collection中并无urlRoot这个属性。或者你直接在fetch方法中定义url的值,以下:
//注意这里bookShelf.url = '/books/'; bookShelf.fetch({ success:function(collection, response, options){ collection.each(function(book){ alert(book.get('title')); }); },error:function(collection, response, options){ alert('error'); } });
其中也定义了两个接受返回值的方法,具体含义我想很容易理解,返回正确格式(json)的数据,就会调用success方法,错误格式的数据就会调用error方法,固然error方法也看添加和success方法同样的形参。
对应的BookShelf的返回格式以下:[{'title':'book0'},{'title':'book1'}.....]
使用这个方法的时候是要和上面的fetch进行配合的,collection在fetch到数据以后,默认状况会调用set方法(set方法向collection里面添加新model,若是该model以前存在则会合并,与此同时会触发collection的add事件),能够经过参数{reset: true}来手动触发reset,reset会整个清空collection从新添加全部model。这时你就须要在collection中定义reset方法或者是绑定reset方法。这里使用绑定演示:
var showAllBooks = function(){ bookShelf.each(function(book){ //将book数据渲染到页面的操做。 document.writeln(book.get('title')); }); } bookShelf.bind('reset',showAllBooks); bookShelf.url = '/books/'; //注意这里bookShelf.fetch({ // 须要主动传递reset,才会触发reset reset: true, success:function(collection, response, options){ collection.each(function(book){ alert(book.get('title')); }); },error:function(collection, response, options){ alert('error'); } });
绑定的步骤要在fetch以前进行。
建立数据,其实就是调用collection的create方法,POST对应的Model对象(json数据)到配置好的url上。以后会返回一个model的实例,以下面代码中的onebook。
var NewBooks = Backbone.Collection.extend({ model: Book, url: '/books/'});var books = new NewBooks;var onebook = books.create({ title: "I'm coming", });
完整代码能够在 code 中找到, 服务器端的代码后面会介绍。
前面介绍了Model和Collection,基本上属于程序中静态的数据部分。这一节介绍Backbone中的router,属于动态的部分,见名知意,router——路由的意思,显然是可以控制url指向哪一个函数的。具体是怎么作的一会经过几个实例来看看。
在如今的单页应用中,全部的操做、内容都在一个页面上呈现,这意味着浏览器的url始终要定位到当前页面。那么一个页面中的左右的操做总不能都经过事件监听来完成,尤为是对于须要切换页面的场景以及须要分享、收藏固定连接的状况。所以就有了router,经过hash的方式(即#page)来完成。不过随着浏览器发展,大多数的浏览器已经能够经过history api来操控url的改变,能够直接使用 /page 来完成以前须要hash来完成的操做,这种方式看起来更为直观一些。下面提供过几个demo来切实体会一番。
var AppRouter = Backbone.Router.extend({ routes: { "*actions" : "defaultRoute" }, defaultRoute : function(actions){ alert(actions); } });var app_router = new AppRouter; Backbone.history.start();
须要经过调用Backbone.history.start()方法来初始化这个Router。
在页面上须要有这样的a标签:
<a href="#actions">testActions</a>
点击该连接时,便会触发defaultRouter这个方法。
看下面例子,立马你就知道了
var AppRouter = Backbone.Router.extend({ routes: { "posts/:id" : "getPost", "*actions" : "defaultRoute" }, getPost: function(id) { alert(id); }, defaultRoute : function(actions){ alert(actions); } });var app_router = new AppRouter; Backbone.history.start();
对应的页面上应该有一个超连接:
<a href="#/posts/120">Post 120</a>
从上面已经能够看到匹配#标签以后内容的方法,有两种:一种是用“:”来把#后面的对应的位置做为参数;还有一种是“*”,它能够匹配全部的url,下面再来演练一下。
var AppRouter = Backbone.Router.extend({ routes: { "posts/:id" : "getPost", //下面对应的连接为<a href="#/download/user/images/hey.gif">download gif</a> "download/*path": "downloadFile", //下面对应的连接为<a href="#/dashboard/graph">Load Route/Action View</a> ":route/:action": "loadView", "*actions" : "defaultRoute" }, getPost: function(id) { alert(id); }, defaultRoute : function(actions){ alert(actions); }, downloadFile: function( path ){ alert(path); // user/images/hey.gif }, loadView: function( route, action ){ alert(route + "_" + action); // dashboard_graph } });var app_router = new AppRouter; Backbone.history.start();
上面的例子都是经过页面点击触发router到对应的方法上,在实际的使用中,还存在一种场景就是须要在某一个逻辑中触发某一个事件,就像是jQuery中得trigger同样,下面的代码展现怎么手动触发router。
routes: { "posts/:id" : "getPost", "manual": "manual", "*actions": "defaultRoute", },// 省略部分代码loadView: function( route, action ){ alert(route + "_" + action); // dashboard_graph},manual: function() { alert("call manual"); app_router.navigate("/posts/" + 404, {trigger: true, replace: true}); }
对应着在页面添加一个a标签: <a href="#/manual">manual</a>
而后点击这个连接,便会触发posts/:id对应的方法。
这里须要解释的是navigate后面的两个参数。trigger表示触发事件,若是为false,则只是url变化,并不会触发事件,replace表示url替换,而不是前进到这个url,意味着启用该参数,浏览器的history不会记录这个变更。
完整代码依然在 code
中能够找到。
前面介绍了存放数据的Model和Collection以及对用户行为进行路由分发的Router(针对连接)。这一节终于能够往页面上放点东西来玩玩了。这节就介绍了Backbone中得View这个模块。Backbone的View是用来显示你的model中的数据到页面的,同时它也可用来监听DOM上的事件而后作出响应。可是这里要提一句的是,相比于Angularjs中model变化以后页面数据自动变化的特性,Backbone要手动来处理。至于这两种方式的对比,各有优劣,能够暂时不关心。
下面依然是经过几个示例来介绍下view的功能,首先给出页面的基本模板:
<!DOCTYPE html> <html> <head> <title>the5fire-backbone-view</title> </head> <body> <div id="search_container"></div> <script type="text/template" id="search_template"> <label><%= search_label %></label> <input type="text" id="search_input" /> <input type="button" id="search_button" value="Search" /> </script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/jquery-1.10.2.js"></script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/underscore-min.1.8.2.js"></script> <script src="http://the5fireblog.b0.upaiyun.com/staticfile/backbone.js"></script><script>(function ($) { //此处添加下面的试验代码})(jQuery);</script></body> </html>
var SearchView = Backbone.View.extend({ initialize: function(){ alert('init a SearchView'); } });var searchView = new SearchView();
是否是以为很没有技术含量,全部的模块定义都同样。
这个属性用来引用DOM中的某个元素,每个Backbone的view都会有这么个属性,若是没有显示声明,Backbone会默认的构造一个,表示一个空的div元素。el标签能够在定义view的时候在属性中声明,也能够在实例化view的时候经过参数传递。
var SearchView = Backbone.View.extend({ initialize: function(){ alert('init a SearchView'); } });var searchView = new SearchView({el: $("#search_container")});
这段代码简单的演示了在实例化的时候传递el属性给View。下面咱们来看看模板的渲染。
var SearchView = Backbone.View.extend({ initialize: function(){ }, render: function(context) { //使用underscore这个库,来编译模板 var template = _.template($("#search_template").html()); //加载模板到对应的el属性中 $(this.el).html(template(context)); } });var searchView = new SearchView({el: $("#search_container")});//这个reander的方法能够放到view的构造函数中//这样初始化时就会自动渲染searchView.render({search_label: "搜索渲染"});
运行页面以后,会发现script模板中的html代码已经添加到了咱们定义的div中。
这里面须要注意的是在模板中定义的全部变量必须在render的时候传递参数过去,否则就会报错。 关于el还有一个东西叫作$el,这个东西是对view中元素的缓存。
页面上的操做除了能够由以前的router来处理以外,在一个view中定义元素,还可使用event来进行事件绑定。这里要注意的是在view中定义的dom元素是指你el标签所定义的那一部分dom节点,event进行事件绑定时会在该节点范围内查找。
来,继续看代码。
var SearchView = Backbone.View.extend({ el: "#search_container", initialize: function(){ this.render({search_label: "搜索按钮"}); }, render: function(context) { //使用underscore这个库,来编译模板 var template = _.template($("#search_template").html()); //加载模板到对应的el属性中 $(this.el).html(template(context)); }, events:{ //就是在这里绑定的 //定义类型为button的input标签的点击事件,触发函数doSearch 'click input[type=button]' : 'doSearch' }, doSearch: function(event){ alert("search for " + $("#search_input").val()); } });var searchView = new SearchView();
本身运行下,是否是比写$("input[type=button]").bind('click',function(){})好看多了。
上面已经简单的演示了模板的用法,若是你用过django模板的话,你会发现模板差很少都是那么回事。上面只是简单的单个变量的渲染,那么逻辑部分怎么处理呢,下面来看下。
把最开始定义的模板中的内容换成下面这个。
<ul> <% _.each(labels, function(name) { %> <% if(name != "label2") {%> <li><%= name %></li> <% } %> <% }); %> </ul>
下面是js代码
var SearchView = Backbone.View.extend({ el: "#search_container", initialize: function(){ var labels = ['label1', 'label2', 'label3']; this.render({labels: labels}); }, render: function(context) { //使用underscore这个库,来编译模板 var template = _.template($("#search_template").html()); //加载模板到对应的el属性中 $(this.el).html(template(context)); }, });var searchView = new SearchView();
再次运行,有木有以为还不错,模板中使用的就基本的js语法。
总结一下,关于view中的东西就介绍这么多,文档上还有几个其余的属性,不过大致用法都一致。在之后的实践中用到在介绍。