问题 backbone.js - 渲染视图


我的ListClass看起来像这样:

var ListView = Backbone.View.extend({

    initialize: function() {
        this.render();
    },  

    events: {
        'click ul#perpage span': 'setperpage'
    },

    setperpage: function(event) {
        this.collection.perpageurl = '/perpage/' + $(event.target).text();
        this.collection.fetch();
        this.render();
    },

    render: function() {

    template = _.template('\
    <table>\
    <% _(collection).each(function(model){%>\
    <tr><td><%=model.id%></td><td><%=model.name%></td><td><%=model.email%></td></tr>\
    <%}); %>\
    </table>\
    <ul id="perpage">\
    <li><span>5</span></li>\
    <li><span>10</span></li>\
    </ul>\
    ');

        var context = {collection: this.collection.toJSON()};
        $(this.el).html(template(context));
        $('#app').html(this.el);
        return this;
    }
});

出于某种原因,当我第一次访问加载此视图的页面时,会显示5个项目(应该会发生)。但是当我点击“setperpage”事件时点击 <span>10</span>,即使网址已更新,然后 fetch() 被调用,列表永远不会更新。 (我已经看过萤火虫的请求了,所以我知道我在json中找回了10个项目)。他们为什么不重新渲染?我仍然只看到5个项目。


10850
2018-04-15 19:08


起源



答案:


this.collection.fetch(); 是异步的,因此对render的调用仍将使用旧数据。

在调用render函数之前,需要等待fetch()完成。

在初始化函数中,将render函数绑定到“reset”事件。

this.collection.on("reset", function() { this.render(); }, this);

当您需要新数据时,请致电

this.collection.fetch({reset: true});

11
2018-04-15 20:17



虽然你的前提是正确的,但你的解决方案是错误的。如果你绑定 this.render 那样的,什么时候 this.render 被调用, this 会提到错误的事情。你必须分配 self = this 然后做 self.render 代替。 - Jamie Wong
好点子;我更新了我的答案以反映这一点。 - Paul Perigny
FWIW,也可以通过使用来解决 this.collection.bind("refresh", (function(self) { return function() {self.render();}; }(this));。您的解决方案可能更清晰。 - Jamie Wong
仅供参考,此功能自v 0.5起重命名为“重置”。我正在相应地更新上面的解决方案。 - mhamrah
保持参考 this 我会用的 _.bind,甚至更好,使用Backbone的 Event.on,第三个参数是可选的上下文: this.collection.on("reset", function() { this.render(); }, this); - Cristi Mihai


答案:


this.collection.fetch(); 是异步的,因此对render的调用仍将使用旧数据。

在调用render函数之前,需要等待fetch()完成。

在初始化函数中,将render函数绑定到“reset”事件。

this.collection.on("reset", function() { this.render(); }, this);

当您需要新数据时,请致电

this.collection.fetch({reset: true});

11
2018-04-15 20:17



虽然你的前提是正确的,但你的解决方案是错误的。如果你绑定 this.render 那样的,什么时候 this.render 被调用, this 会提到错误的事情。你必须分配 self = this 然后做 self.render 代替。 - Jamie Wong
好点子;我更新了我的答案以反映这一点。 - Paul Perigny
FWIW,也可以通过使用来解决 this.collection.bind("refresh", (function(self) { return function() {self.render();}; }(this));。您的解决方案可能更清晰。 - Jamie Wong
仅供参考,此功能自v 0.5起重命名为“重置”。我正在相应地更新上面的解决方案。 - mhamrah
保持参考 this 我会用的 _.bind,甚至更好,使用Backbone的 Event.on,第三个参数是可选的上下文: this.collection.on("reset", function() { this.render(); }, this); - Cristi Mihai