使用Underscore.js的template将Backbone.js的js代码和html代码分离
这段时间在学习Require.js和Backbone.js的过程中,发现有些项目里的HTML代码都是写在View的js代码里面的,渲染的时候需要对Collection进行循环,再将HTML代码拼接上去,这似乎不是一件非常好的事情,因为将js代码和html代码融合到一起会增加代码的维护难度,而且这个过程中考虑到性能的因素,需要将HTML代码放到一个数组中,最后进行拼接,代码写起来比较麻烦。我看到他们的代码之后就在考虑是否有一种类似php模板引擎的东西可以将Collection传递进去然后渲染。
我查阅了Backbone.js的手册http://backbonejs.org/#View-template ,里面有一段文字:
However, we suggest choosing a nice JavaScript templating library. Mustache.js, Haml-js, and Eco are all fine alternatives. Because Underscore.js is already on the page, _.template is available, and is an excellent choice if you prefer simple interpolated-JavaScript style templates.
Whatever templating strategy you end up with, it’s nice if you never have to put strings of HTML in your JavaScript.
它建议我们使用js的模板库,而刚好Backbone.js强依赖于Underscore.js所以Underscore.js已经被引入了,它提供了一个_.template方法,这个方法支持使用内嵌js代码的html模板代码,在js代码里没有出现HTML代码是一件非常nice的事情!这正符合了我们MVC的思想,前端的HTML代码也便于维护,要不然就真的成为意大利面条式代码了!
关于Underscore.js的template的说明在http://underscorejs.org/#template ,这里有教你怎么使用。
Template functions can both interpolate variables, using <%= … %>, as well as execute arbitrary JavaScript code, with <% … %>. If you wish to interpolate a value, and have it be HTML-escaped, use <%- … %>
上面这段文字告诉我们在这个模板的代码里面js内嵌代码的标签如何使用,接下来我举一个例子:
我们先建一个template,位于:template/album/index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<% var title = ‘My albums‘; document.title = title; %> < h1 ><%= title %></ h1 > < p > < a href = "album-rest/add" >Add new album</ a > </ p > < table class = "table" > < thead > < tr > < th >Title</ th > < th >Artist</ th > < th > </ th > </ tr > </ thead > < tbody id = "album-list" > <% _.each(albums, function(album) { %> < tr class = "album-row" > < td ><%= album.get(‘title‘) %></ td > < td ><%= album.get(‘artist‘) %></ td > < td > < a href="album-rest/edit/<%= album.get(‘id‘) %>">Edit</ a > < a href="album-rest/delete/<%= album.get(‘id‘) %>">Delete</ a > </ td > </ tr > <% }); %> </ tbody > </ table > |
下面的这个代码片段是定义了一个Backbone的View,sync属性会去请求服务端获取获取所有album的数据,最后将数据存放到albumList这个Collection里面。随后执行render方法,在render里面this.template = _.template(AlbumTpl, albums);这句代码就是用来完成数据和模板混合的工作的,AlbumTpl来自template/album/index.html,另外必须要将Collection中的所有的model以数组的形式获取到赋给albums,除非你在模板里面又进行了对Collection的解析操作,否则不能只传入一个Collection,因为Underscore.js的template是无法识别Backbone.js的Collection的对象结构的。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
define([ "model/album" , "collection/album-list" , "text" , ‘text!template/album/index.html‘ ], function (Album, AlbumList, text, AlbumTpl) { var IndexView = Backbone.View.extend({ model : Album, initialize: function () { }, sync : function (render) { var albumList = new AlbumList; var view = this ; Backbone.sync( ‘read‘ , albumList, { success : function (result) { albumList.add(result.ret); view.collection = albumList; view.render(); } }); }, render: function () { albumList = this .collection; albums = albumList.models; console.log(_.template(AlbumTpl, albums)); this .template = _.template(AlbumTpl, albums); $( "#page-wrapper" ).html( this .template); } }); return IndexView; }); |
通过上面的操作,就可以实现js代码和html代码分离了。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。