// Models company.models.Employee = Backbone.Model.extend({ defaults: { id: undefined, name: undefined } }); // Collections company.collections.Department = Backbone.Collection.extend({ model: company.models.Employee }); // Views company.views.EmployeeList = Backbone.View.extend({ el: "#container", render: function() { ... } }); // Create base data var c = new company.collections.Department( [{id:1, name: "Star Willard"}, {id:2, name: "Rhona Eggleston"}, {id:3, name: "Cassi Chowdhury"}, {id:4, name: "Leigh Nilson"}, {id:5, name: "Niesha Auger"} ]); // Create view var v = new company.views.EmployeeList({collection: c}); v.render();
以下就來探討 render function 該怎麼把 collection 套用到 template 並呈現在 UI 上
方法一:土法煉鋼,串成 string
這種方法當然是很差啦,程式可讀性下降,也很難維護
Render function in app.js
render: function() { var that = this; this.collection.each(function(m) { var html = "<div>" + "" + m.get("id") + " " + "" + m.get("name") + "" + "</div>"; that.$(".list").append(html); }); return this; }
方法二:寫在 stript 內
利用 underscore.js template engine
比前一種好一點點,但還是有缺點,沒有把 template 切出去,一方面 IDE 的 syntax 會失效
in index.html
<script id="template-item" type="text/template"> <div> <b><%= id %></b> <u><%= name %></u> </div> </script>Render function in app.js
template: _.template($("#template-item").html()), render: function() { var that = this; this.collection.each(function(m) { that.$(".list").append(that.template(m.toJSON())); }); return this; }
方法三:從獨立的 html 檔案中讀取
把 template 寫在個別的 html 檔,利用 ajax 的方式去 load。
程式碼較好管理,但每讀取一次 template 就要多發一個 http request
tpl/template-item.html
<%= id %> <%= name %>
Add the template manager to app.js
其實只是把 get request 包起來啦
company.utils.TemplateManager = { load: function(name, callback) { $.get('tpl/' + name + '.html', function(data) { callback(data); }); } };
Render function in app.js
render: function() { var that = this; company.utils.TemplateManager.load('template-item', function(data) { var tpl = _.template(data); that.collection.each(function(m) { that.$(".list").append(tpl(m.toJSON())); }); }); return this; }
方法四:Asynchronously load template
與其說是非同步,正確來說應該是預先載入(preload),之後使用時就可以直接從 local variable 取出,加快反應速度,也可以省去從 server 抓取相同 template 的功耗
TemplateLoader in app.js
company.utils.TemplateManager = { templates: {}, load: function(names) { var that = this; $.each(names, function(index, name) { $.get('tpl/' + name + '.html', function(data) { that.templates[name] = data; }); }); }, get: function(name, callback) { return this.templates[name]; } };
Render function in app.js
render3: function() { var that = this; var tpl = _.template(company.utils.TemplateManager.get('template-item')); this.collection.each(function(m) { that.$(".list").append(tpl(m.toJSON())); }); }
in app.js
Preload the template before render the view.
company.utils.TemplateManager.load(['template-item', 'other-template']); var v = new company.views.EmployeeList({collection: c}); v.render();
如果要保證全部的 template 都載入才進行之後的事情,可以使用 jquery.when()
load: function(names, callback) { var deferreds = []; var that = this; $.each(names, function(index, name) { deferreds.push($.get('tpl/' + name + '.html', function(data) { that.templates[name] = data; })); }); $.when.apply(null, deferreds).done(callback); }
參考資料
沒有留言:
張貼留言