0

在父视图中渲染子视图时,我试图解决这个问题。

父视图是一个静态的 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-pane 中呈现子视图):

<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>

两者都按顺序呈现,但子视图不呈现任何数据,只是表头。

无法弄清楚如何让它工作?

4

3 回答 3

1

您应该在追加时指定孩子的 el。

this.$el.append(this.innerView.render());

this.$el.append(this.innerView.render().el);
于 2013-04-19T07:49:28.607 回答
1

有关您的部分问题,请参阅 RullDawg 的答案。
另一部分是您在升级到Backbone 1.0时可能会错过一些事情。

"将 Collection 的 "update" 重命名为 set,与类似的 model.set() 并行,并与 reset 对比。它现在是获取后的默认更新机制。如果您想继续使用 "reset",请通过 {reset : 真的}。

所以基本上,你渲染子视图的唯一时间是在父视图中渲染它时(我不知道你为什么要这样做)。reset你在它从未被触发的时候收听它。将其更改为this.collection.fetch({reset: true});并注意要附加到 DOM 的内容,它应该可以工作。

如果您不想使用该reset标志,则可以收听更通用的sync事件。

于 2013-04-19T08:01:13.917 回答
1

我的理解是,当集合在后端有数据时,它不会呈现数据。现在你的代码有一个缺陷。fetch() 是异步调用。因此,要确保您的数据在渲染视图时可用,就是编写成功处理程序。并将您的 fetch 逻辑移动到 render() 函数,例如,如果我在 OverAllLeatherBoardView 中看到您的 fetch 代码

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()}));
        }  
于 2013-04-19T09:13:04.730 回答