尝试在父视图中渲染子视图时解决此问题。
父视图是一个静态的html块,它将是用于过滤子视图的选项卡,子视图是从服务器中提取的表格数据。
问题是父视图和子视图渲染正常,但子视图的集合没有数据;但我可以确认该服务正在控制台中返回数据。
这是我的路由器:
define([
'domLib',
'underscore',
'backbone',
'bootstrap',
'view/logged-out',
'view/leaderboard',
'view/leaderboard-filter',
'view/leaderboard-overall',
'view/login',
'view/navigation'
], function($, _, Backbone, Bootstrap, LoggedOutView, LeaderboardView, LeaderboardFilter, OverallLeaderboardView, LoginView, NavigationView) {
var AppRouter = Backbone.Router.extend({
routes: {
'': 'index',
'leaderboard': 'leaderboard',
'login': 'login'
},
index: function () {
var loggedOutView = new LoggedOutView();
},
leaderboard: function(){
var leaderboardFilter = new LeaderboardFilter();
//var overallLeaderboardView = new OverallLeaderboardView();
},
login: function(){
var loginView = new LoginView();
}
});
var initialize = function(){
var app_router = new AppRouter,
leaderboardView = new LeaderboardView(),
navigationView = new NavigationView();
Backbone.history.start();
};
return {
initialize: initialize
};
});
我的父视图,从路由器调用:
define([
'domLib',
'underscore',
'backbone',
'router',
'view/leaderboard-overall',
'text!template/leaderboard-filter.html'
],
function($, _, Backbone, Router, OverallLeaderboardView, LeaderboardFilterTemplate) {
var LeaderboardFilterView = Backbone.View.extend({
el: 'section[role="main"]',
template: _.template(LeaderboardFilterTemplate),
initialize: function(){
this.innerView = new OverallLeaderboardView();
this.render();
},
render: function(){
this.$el.append(this.template());
this.$el.append(this.innerView.render());
}
});
return LeaderboardFilterView;
});
然后我想在父视图模板HTML中呈现一个表视图:
define([
'domLib',
'underscore',
'backbone',
'router',
'collection/leaderboard-overall',
'text!template/leaderboard-overall.html'
],
function($, _, Backbone, Router, OverallLeaderboardCollection, OverallLeaderboardTemplate) {
var OverallLeaderboardView = Backbone.View.extend({
el: 'section[role="main"]',
template: _.template(OverallLeaderboardTemplate),
initialize: function(){
this.collection = new OverallLeaderboardCollection();
this.collection.bind('reset', _.bind(this.render, this));
this.collection.fetch();
},
render: function(){
console.log('render overall leaderboard');
this.$el.append(this.template({players: this.collection.toJSON()}));
}
});
return OverallLeaderboardView;
});
父模板(想要在.tab窗格中呈现子视图):
<nav id="leaderboard-filter">
<ul class="nav nav-tabs">
<li class="active"><a href="#all-time">All Time</a></li>
<li><a href="#today">Today</a></li>
<li><a href="#week">This Week</a></li>
<li><a href="#month">This Month</a></li>
</ul>
</nav>
<section>
<div class="tab-content">
<div class="tab-pane">
<!-- Render leaderboard -->
</div>
</div>
</section>
子视图:
<table class="table table-bordered table-striped">
<thead>
<tr>
<th>Rank</th>
<th>Player</th>
<th>Games Completed</th>
<th>High Score</th>
<th>Percent Correct</th>
<th>Avg Answer Time</th>
<th>Cumulative Score</th>
</tr>
</thead>
<tfoot>
<!-- Logged in user details here -->
</tfoot>
<tbody>
<% _.each(players, function(player, index){ %>
<tr>
<td><%= index + 1 %></td>
<td><a href="/hyc-web/"><%= _.escape(player.user) %></a></td>
<td><%= player.games_completed %></td>
<td><%= player.high_score %></td>
<td><%= player.percent_correct %></td>
<td><%= player.avg_answer_time %></td>
<td><%= player.cumulative_score %></td>
</tr>
<% }); %>
</tbody>
</table>
两者都按顺序渲染,但子视图不会仅仅为表头呈现任何数据。
可以;弄清楚如何使这个工作?
答案 0 :(得分:1)
您应该在追加时指定孩子的el。
这
this.$el.append(this.innerView.render());
要
this.$el.append(this.innerView.render().el);
答案 1 :(得分:1)
请参阅RullDawg对部分问题的回答 另一部分是,在升级到Backbone 1.0时,您可能会错过一些事情。
“重命名集合的”更新“以设置,与类似的model.set()并行,并与reset对比。它现在是获取后的默认更新机制。如果你想继续使用”重置“,传递{reset:true}。”
所以基本上,你渲染你的子视图的唯一时间是你在父视图中渲染它(我不知道你为什么要这样做btw)。您在reset
事件从未触发时收听。将其更改为this.collection.fetch({reset: true});
,并注意您要添加到DOM的内容,它应该可以正常工作。
如果您不想使用reset
标记,则可以收听更通用的sync
事件。
答案 2 :(得分:1)
我的理解是,当集合在后端有数据时,它不会渲染数据。 现在你的代码存在缺陷。 fetch()是异步调用。 因此,为了确保您的数据可用,而渲染视图是写入成功处理程序。 并将你的fetch逻辑移动到render()函数 例如 如果我在OverAllLeatherBoardView中看到你的提取代码
initialize: function(){
this.collection = new OverallLeaderboardCollection();
this.collection.bind('reset', _.bind(this.render, this));
//this.collection.fetch(); move it to render function
},
render: function(){
console.log('render overall leaderboard');
this.collection.fetch({success: $.proxy(myDelegate, this)})
//this.$el.append(this.template({players: this.collection.toJSON()})); move it to delegate
},
//here you go
mDelegate:function(model, response, options){
this.$el.append(this.template({players: model.toJSON()}));
}