Backbone 子视图为父视图调用渲染

Backbone subview calling render for parent

我有一个 backbone 页面,其行为如下。

Collection - > Models -> Views

因为我有一个包含 N 长度搜索结果的集合。这些模型中的每一个都与视图的一个实例相关联,在本例中是显示的一行数据。

我希望能够将每一行从他们的 'details' 视图切换到他们的 'advanced' 视图,其中包含更多信息。目前,我有父视图为每个模型呈现 N 个视图。我可以通过更新模型和监听更改事件来切换状态更改,然后只重新渲染我单击的视图部分。这样做时我注意到一个问题。问题是视口跳转到页面顶部,这不是很好的用户体验。

调试时我发现了一些奇怪的东西

正在调用父视图(保存搜索结果的页面)的渲染函数,而父视图又调用每一行的渲染函数。我认为这就是导致每个子视图重新呈现的原因。

这里有一些代码示例来演示问题:

// The child view's render and initialis
    var SearchInviteRow = Backbone.View.extend({

    tagName:  "invite-section-result-row",

    initialize: function(params){
        this.template = templateHTML;
        this.extendedTemplate = extendedTemplate;
        this.listenTo(this.model, 'change', this.render);
    },

    events : {
        "click .toggle-attachments" : "renderWithAttachments"
    },   

    render: function(){
        var view = this, render;
        var that = this;

        if(!this.model.get("expand")){
            var rendered = Mustache.render(view.template, that.model.toJSON());
            this.$el.html(rendered);
        } else {

            var rendered = Mustache.render(view.extendedTemplate, that.model.toJSON());
            this.$el.html(rendered);
        }

        return this;
    },  

    close: function(){
        this.remove();          
    },

    renderWithAttachments: function(){
        if( !this.model.get("expand") ) {
            this.model.set( {"expand" : true } );
            this.model.getAttachments();
        } else {
            this.model.set( {"expand" : false } );
        }

    }
});

这是父级呈现的一部分,它遍历集合,将行附加到搜索图块。

   for (var i = 0; i < this.collection.length; i++) {

            view.subViewArray[i] = new SearchInviteRow({
                model: this.collection.at(i)
            });

            this.$(".invite-section-inside").append(view.subViewArray[i].render().el);

        }

我无法解决的是为什么调用父级的渲染函数导致了我的其他问题。

有两种情况会发生这种情况,一种是如果您正在监听 collection 上的 backbone 事件,第二种是如果触发的是 DOM 事件。

对于 backbone 事件,如果您查看 documentation,您会发现在 collection 中的模型上触发的事件也会在 collection 中触发]本身

Any event that is triggered on a model in a collection will also be triggered on the collection directly, for convenience. This allows you to listen for changes to specific attributes in any model in a collection, for example: documents.on("change:selected", ...)

在这种情况下,您应该检查事件回调是否要对其进行操作(查看是什么触发了它,也许在触发事件时传入 extra flag),或者确保您只听您有兴趣采取行动的特定事件。例如,您可能不想听 collection 的通用 change 事件,而是想听更具体的版本 (change:someProperty)。

对于 DOM 事件,如果您在 parents 视图中收听与 [=30] 相同的选择器,则很容易发生这种情况=] 的观点,因为 parent 的根 el 也是 child 的 el.

的 parent