【发布时间】:2012-06-28 20:27:51
【问题描述】:
我的问题的快速总结:视图的第一次渲染包含集合中的元素,而第二次渲染不包含。请继续阅读以了解详细信息...
另外值得注意的是:我确实意识到以下代码代表了幸福的道路,并且有很多潜在的错误处理代码丢失,等等,等等......这是为了简洁而故意的。
我对backbone.js 还是很陌生,在找出正确的方法来为以下场景实施解决方案时遇到了一些麻烦:
我有一个带有两个主要区域的页面,用于包含/显示将成为应用程序主要布局的渲染内容。一般来说,它看起来像这样:
-------------------------------------------
| | |
| | |
| Content | Actions |
| Panel | Panel |
| | |
| | |
| | |
| | |
| | |
| | |
-------------------------------------------
我有一个从中获取数据的 HTTP API,它实际上以 JSON 结果的形式提供各种模块的资源信息,这些信息来自对每个模块的基本 URL 的 OPTIONS 调用。例如,对http://my/api/donor-corps 的OPTIONS 请求返回:
[
{
"Id":0,
"Name":"GetDonorCorps",
"Label":"Get Donor Corps",
"HelpText":"Returns a list of Donor Corps",
"HttpMethod":"GET",
"Url":"https://my/api/donor-corps",
"MimeType":"application/json",
"Resources":null
}
]
该应用程序有一个我称之为DonorCorpsCollection 的主干集合,它将是DonorCorpModel 对象的只读集合,可能由多个不同的主干视图呈现并以不同的方式显示在不同页面上应用程序(最终......后来......目前情况并非如此)。 DonorCorpsCollection 的 url 属性需要是具有“GetDonorCorps”Name 属性的对象的 Url 属性,该属性是初始 OPTIONS 调用的结果,以获取 API 模块资源(如上所示)。
该应用程序的顶部有一个菜单栏,其中包含链接,单击该链接将呈现应用程序的各个页面。目前,应用程序中只有两个页面,“主页”页面和“预排序”页面。在“主页”视图中,两个面板中都只有占位符信息,指示用户应单击菜单栏上的链接来选择要执行的操作。当用户单击“预排序”页面链接时,我只想显示一个主干视图,该视图将DonorCorpsCollection 呈现为操作面板中的无序列表。
我目前正在使用JavaScript module pattern 来组织和封装我的应用程序代码,我的模块目前看起来像这样:
var myModule = (function () {
// Models
var DonorCorpModel = Backbone.Model.extend({ });
// Collections
var DonorCorpsCollection = Backbone.Collection.extend({ model : DonorCorpModel });
// Views
var DonorCorpsListView = Backbone.View.extend({
initialize : function () {
_.bindAll(this, 'render');
this.template = _.template($('#pre-sort-actions-template').html());
this.collection.bind('reset', this.render); // the collection is read-only and should never change, is this even necessary??
},
render : function () {
$(this.el).html(this.template({})); // not even exactly sure why, but this doesn't feel quite right
this.collection.each(function (donorCorp) {
var donorCorpBinView = new DonorCorpBinView({
model : donorCorp,
list : this.collection
});
this.$('.donor-corp-bins').append(donorCorpBinView.render().el);
});
return this;
}
});
var DonorCorpListItemView = Backbone.View.extend({
tagName : 'li',
className : 'donor-corp-bin',
initialize : function () {
_.bindAll(this, 'render');
this.template = _.template($('#pre-sort-actions-donor-corp-bin-view-template').html());
this.collection.bind('reset', this.render);
},
render : function () {
var content = this.template(this.model.toJSON());
$(this.el).html(content);
return this;
}
});
// Routing
var App = Backbone.Router.extend({
routes : {
'' : 'home',
'pre-sort', 'preSort'
},
initialize : function () { },
home : function () {
// ...
},
preSort : function () {
// what should this look like??
// I currently have something like...
if (donorCorps.length < 1) {
donorCorps.url = _.find(donorCorpResources, function (dc) { return dc.Name === "GetDonorCorps"; }).Url;
donorCorps.fetch();
}
$('#action-panel').empty().append(donorCorpsList.render().el);
}
})
// Private members
var donorCorpResources;
var donorCorps = new DonorCorpsCollection();
var donorCorpsList = new DonorCorpsListView({ collection : donorCorps });
// Public operations
return {
Init: function () { return init(); }
};
// Private operations
function init () {
getAppResources();
}
function getAppResources () {
$.ajax({
url: apiUrl + '/donor-corps',
type: 'OPTIONS',
contentType: 'application/json; charset=utf-8',
success: function (results) {
donorCorpResources = results;
}
});
}
}(myModule || {}));
最后,这一切都使用了以下 HTML:
...
<div class="row-fluid">
<div id="viewer" class="span8">
</div>
<div id="action-panel" class="span4">
</div>
</div>
...
<script id="pre-sort-actions-template" type="text/template">
<h2>Donor Corps</h2>
<ul class="donor-corp-bins"></ul>
</script>
<script id="pre-sort-actions-donor-corp-bin-view-template" type="text/template">
<div class="name"><%= Name %></div>
</script>
<script>
$(function () {
myModule.Init();
});
</script>
...
到目前为止,我已经能够在我单击“预排序”菜单链接时第一次使用它。当我单击它时,它会按预期呈现捐赠者军团的列表。但是,如果我然后单击“主页”链接,然后再次单击“预排序”链接,这次我会看到标题,但 <ul class="donor-corp-bins"></ul> 是空的,其中没有列表项。 ...而且我不知道为什么或我需要做不同的事情。我觉得我一般理解backbone.js 视图和路由器,但在实践中,我显然遗漏了一些东西。
总的来说,这似乎是一个相当简单的场景,我不觉得我在这里尝试做任何特殊的事情,但我无法让它正常工作,而且似乎无法弄清楚出为什么。非常感谢您的协助,或至少向正确方向轻推。
【问题讨论】:
标签: backbone.js backbone-views backbone-routing