[英]How can I make underscore templates interact with each other?
我的Backbone.js項目中有兩種模板。 單項模板和項列表模板。
此外,項目中有兩種視圖類型:單項模板和項列表。
我使用RequireJS來使應用程序模塊化。 因此,我想,將模板也分開也是一個好習慣。 但是有一個問題:我無法使我的模板進行“交流”。 呈現CollectionView時,它在頁面中僅包含一個元素-空的<ul id="spaceman-list">
並且其中沒有任何項目集合。 在我的列表視圖中,我使用addItem函數通過itemView包裝每個集合項,但是它不起作用。 該列表只是不在dom中呈現。
我不想使用_.each()
這樣的混亂東西,我想保持代碼干凈。
這是兩個視圖的代碼:列表視圖
// app/js/views/spaceman-list.js
'use strict';
(function(w) {
define([
'jquery',
'underscore',
'backbone',
'../models/spaceman',
'../views/spaceman-item',
'../collections/spaceman-collection',
'text!../templates/spaceman-list.html'
], function($, _, Backbone, SpacemanModel, SpacemanItemView, SpacemanCollection, listTemplate) {
var SpacemanListView = Backbone.View.extend({
el: '#container',
render: function() {
this.collection.on('reset', this.addItem, this);
this.collection.each(this.addItem, this);
var data = {
spacemen: this.collection.models
};
var compiled = _.template(listTemplate, data);
this.$el.html(compiled);
return this;
},
addItem: function(item) {
var newSpaceman = new SpacemanItemView({model: item});
this.$el.find('ul').append(newSpaceman.render());
}
});
return SpacemanListView;
});
})(window);
和項目視圖:
// app/js/views/spaceman-item.js
'use strict';
(function(w) {
define([
'jquery',
'underscore',
'backbone',
'../models/spaceman',
'text!../templates/spaceman-item.html'
], function($, _, Backbone, SpacemanItem, itemTemplate) {
var SpacemanItemView = Backbone.View.extend({
el: '#spaceman-list',
render: function() {
var data = {
spaceman: this.model
};
this.$el.html(_.template(itemTemplate, data));
},
});
return SpacemanItemView;
});
})(window);
而且,正如我在上文所述,我將下划線模板分開放置:這是列表模板:
// app/js/templates/spaceman-list.html
<ul id="spaceman-list"></ul>
這是項目模板:
// app/js/templates/spaceman-item.html
<li><% spaceman.get('name') %></li>
另外,我在這里添加我的應用程序入口點:
// app/js/application.js
'use strict';
(function(w) {
define([
'jquery',
'underscore',
'backbone',
'collections/spaceman-collection',
'views/spaceman-list'
// Request router.js
], function($, _, Backbone, ItemsList, ListView) {
var App = Backbone.View.extend({
initialize: function(){
// Pass in our Router module and call it's initialize function
console.log('Yeeha!');
var endurance = new ItemsList([
{name: 'Cooper'},
{name: 'Brend'},
{name: 'Romilly'},
{name: 'Doyle'},
{name: 'Mann'}
]);
console.log(endurance);
var view = new ListView({collection:endurance});
view.render();
}
});
return App;
});
})(window);
我只是為此而瘋狂。 如何制作單獨的模板以彼此“看到”?
您在SpacemanListView#addItem
這樣說:
this.$el.find('ul').append(newSpaceman.render())
但SpacemanItemView#render
不返回任何內容:
render: function() {
var data = {
spaceman: this.model
};
this.$el.html(_.template(itemTemplate, data));
},
SpacemanItemView
還說:
el: '#spaceman-list'
因此,當所有SpacemanItemView
實例的render
函數都說this.$el.html(...)
時,它們將嘗試使用相同的el
。 大概您的templates/spaceman-list.html
包含<ul id="spaceman-list">
或類似的內容,因此#spaceman-list
將集合視圖放置在頁面上之前不會解析為任何內容; 但您是在頁面上的集合視圖之前調用addItem
,因此所有項目視圖都試圖呈現為同一不存在的元素。
解決方案是雙重的:
render
函數通常return this;
以便調用者可以$container.append(view.render().el)
將內容放到頁面上,因此可以這樣做。 el
(即, el: '#something'
視圖定義中的el: '#something'
)會導致各種排序和事件問題,當每個視圖創建並擁有自己的el
時,效果會更好。 addItem
應該看起來像這樣:
addItem: function(item) {
var newSpaceman = new SpacemanItemView({model: item});
this.$('ul').append(newSpaceman.render().el);
}
請注意this.$
快捷方式和append
調用中的.el
。
然后我們重新處理項目視圖:
var SpacemanItemView = Backbone.View.extend({
tagName: 'li',
render: function() {
var tmpl = _.template(itemTemplate);
this.$el.html(tmpl({ spaceman: this.model }));
return this;
},
});
沒有更多的el
但是現在我們有了tagName: 'li'
,這將告訴Backbone創建一個空的<li>
作為視圖的el
。 el
文檔介紹了如何使用各種視圖屬性來確定el
將是什么。
還要注意_.template(tmpl, data)
形式在_.template
1.7.0中停止工作,因此我也修復了該問題。
您還可以調整templates/spaceman-item.html
模板,使其僅作為<li>
的內容:
<% spaceman.get('name') %>
我建議對集合視圖進行類似的更改,以便它也創建並擁有它的el
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.