我的Backbone.js项目中有两种类型的模板。 单项模板和项目清单模板。
此外,项目中有两种类型的视图: 单项模板和项目列表。
我使用RequireJS来使应用程序模块化。所以,我想,保持模板分离是一个很好的做法。但是有一个问题:我不能让我的模板“沟通”。当我渲染CollectionView时,它只在页面中生成一个元素 - 空<ul id="spaceman-list">
并且其中没有项目集合。在我的listview中,我使用addItem functuion按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入口点:
// 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);
我只是为此疯狂。如何制作单独的模板以“看到”彼此?
答案 0 :(得分:1)
你在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
函数说el
时,所有render
个实例都会尝试使用相同的this.$el.html(...)
。大概是您的templates/spaceman-list.html
包含<ul id="spaceman-list">
或类似内容,因此#spaceman-list
在收集视图放置在页面上之前不会解析为任何内容;但是你在集合视图出现在页面之前调用addItem
,所以项目视图都试图渲染到同一个不存在的元素中。
解决方案有两个方面:
render
函数传统上return this;
,以便调用者可以$container.append(view.render().el)
将内容放在页面上,这样做。el
(即el: '#something'
)会导致各种排序和事件问题,当每个视图创建并拥有自己的el
时,事情会更好。< / LI>
醇>
addItem
看起来应该更像这样:
addItem: function(item) {
var newSpaceman = new SpacemanItemView({model: item});
this.$('ul').append(newSpaceman.render().el);
}
注意this.$
快捷方式和.el
来电中的append
。
然后我们重新审视项目视图:
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
documentation涵盖了各种视图属性如何用于确定el
的内容。
另请注意_.template(tmpl, data)
_.template
形式的templates/spaceman-item.html
stopped working in Underscore 1.7.0,所以我也解决了这个问题。
您还需要调整<li>
模板,使其只是<% spaceman.get('name') %>
的内容:
el
我建议对集合视图进行类似的更改,以便它也创建并拥有其pip uninstall setuptools
download https://bitbucket.org/pypa/setuptools/raw/0.7.3/ez_setup.py
。