【发布时间】:2015-07-17 13:24:18
【问题描述】:
我有一个主干页面,其行为如下。
Collection - > Models -> Views
我有一个包含 N 长度的搜索结果的集合。这些模型中的每一个都与视图的一个实例相关联,在本例中是显示的一行数据。
我希望能够将每一行从“详细信息”视图切换到包含更多信息的“高级”视图。目前我有父视图为每个模型渲染 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);
}
我无法解决的是为什么要调用父级的渲染函数,这导致了我的其他问题。
【问题讨论】:
-
你还没有发布你的父母视图或你的标记,所以很难确定,但如果你使用相同的选择器为你的事件散列然后因为事件被委托给根 el 并且父母的意见根 el 也是孩子的 *e*` 的父母,它也会被触发。
-
@Jack 我刚刚阅读了更多内容,似乎模型上的事件会冒泡到其父集合中。这将导致父级重新渲染。是否可以停止事件传播?
-
不完全是,但在您的事件回调中,您应该能够看到触发事件的原因并采取相应措施。那就是说,如果您不想采取行动,为什么您的集合视图会监听模型 expand 事件?
-
@Jack 集合现在显式监听模型更改事件。显然,模型更改事件将启动其父集合的更改事件。所以我正在更改模型上的一个属性,该属性又发送一个事件来表示集合已更改,这反过来又重新渲染了父视图。 stackoverflow.com/questions/9951222/…
-
也许您应该听听您感兴趣的特定(或多个特定)事件(例如
this.listenTo(this.collection, 'change:someProperty',this.render);),而不是听集合中的任何模型更改事件
标签: javascript backbone.js model-view-controller view render