backbonejs 在 parent 模型更改时再次渲染 parent 视图而不渲染 children
backbonejs render parentview without rendering children again on parent model change
我在带有嵌套集合的 backbonejs 中遇到了一些架构问题。我有模型集合,在每个模型中它可以包含与 childrens 相同模型的集合。所以在 parent 视图渲染中,我正在渲染 child 集合并将其 dom 附加到 parent 视图。它工作得很好。
但是在 parent 模型更改时,我 re-rendering 它的视图导致其 childrens 再次渲染。但是当 parent 的模型发生变化时,我不会创建子项 dom,因为 child 集合没有变化。我可以在没有 re-rendering 的情况下使用 children dom 吗?有什么办法可以实现吗?
Parent查看代码:
RowView.prototype.initialize = function(options) {
this.childCollection = options.childCollection;
this.listenTo(this.model, "change", this.render);
}
RowView.prototype.render = function() {
var existingControls = this.model.get("controls").toJSON();
this.childCollection = this.model.get("controls");
this.childCollection.bind('add', this.addOneChild, this);
this.childCollection.bind('reset', this.resetChildrens, this);
this.childCollection.reset(existingControls, this);
};
RowView.prototype.addOneChild = function(respModel) {
view = new RowViewChildView({
model: respModel,
parentView: this
});
this.$el.find('.childrens').append(view.render().el);
};
RowView.prototype.resetChildrens = function(currentCollection) {
this.$el.find(".childrens").html('');
return this.addAllChildrens();
};
RowView.prototype.addAllChildrens = function() {
return this.childCollection.each(this.addOneChild, this);
};
我也不想松动 child 查看事件。
提前致谢
很遗憾,我还不能发表评论,所以我会创建一个答案。
我不完全确定您要实现的目标,因为看起来您的渲染方法只包含用于渲染子级的代码而没有特定于渲染父级的代码,您是否遗漏了它?
不过,您可以尝试使用渲染和重新渲染功能。重新渲染函数只会渲染已更改的父级 DOM 部分(parent-markup 以下的所有内容)。
render: function () {
//render everything below .parent
}
rerender: function () {
//render stuff below parent-mark-up
}
HTML可以拆分
<div class="parent">
<div class="parent-markup"></div>
<div class="children"></div>
</div>
如果你确实需要渲染整个父元素并想重用子元素 DOM 你可以只保护 el 然后再次附加它,之后使用 this.delegateEvents();
来确保 Events a又被冒泡了。
一般我会把监听器放在初始化函数中,推荐使用this.listenTo(this.childCollection , 'add', this.callback);
Backbonejs: .on vs .listenTo vs .bind
最后我建议使用像这样的模块化语法
var RowView = Backbone.View.extend({
initialize: function(options) {}
render: function() {}
});
更新:这是一个fiddle:https://jsfiddle.net/gs4r8k10/30/
您可以使用 jQuery detach()
分离现有子项 DOM 并在父项 re-renders 之后再次附加它们。
如果可以像
if(this.childrenAlreadyRendered){
// special performant rendering with detach
}
在您的 render
方法中。 marionette 做这样的智能渲染。
我在带有嵌套集合的 backbonejs 中遇到了一些架构问题。我有模型集合,在每个模型中它可以包含与 childrens 相同模型的集合。所以在 parent 视图渲染中,我正在渲染 child 集合并将其 dom 附加到 parent 视图。它工作得很好。
但是在 parent 模型更改时,我 re-rendering 它的视图导致其 childrens 再次渲染。但是当 parent 的模型发生变化时,我不会创建子项 dom,因为 child 集合没有变化。我可以在没有 re-rendering 的情况下使用 children dom 吗?有什么办法可以实现吗?
Parent查看代码:
RowView.prototype.initialize = function(options) {
this.childCollection = options.childCollection;
this.listenTo(this.model, "change", this.render);
}
RowView.prototype.render = function() {
var existingControls = this.model.get("controls").toJSON();
this.childCollection = this.model.get("controls");
this.childCollection.bind('add', this.addOneChild, this);
this.childCollection.bind('reset', this.resetChildrens, this);
this.childCollection.reset(existingControls, this);
};
RowView.prototype.addOneChild = function(respModel) {
view = new RowViewChildView({
model: respModel,
parentView: this
});
this.$el.find('.childrens').append(view.render().el);
};
RowView.prototype.resetChildrens = function(currentCollection) {
this.$el.find(".childrens").html('');
return this.addAllChildrens();
};
RowView.prototype.addAllChildrens = function() {
return this.childCollection.each(this.addOneChild, this);
};
我也不想松动 child 查看事件。
提前致谢
很遗憾,我还不能发表评论,所以我会创建一个答案。
我不完全确定您要实现的目标,因为看起来您的渲染方法只包含用于渲染子级的代码而没有特定于渲染父级的代码,您是否遗漏了它?
不过,您可以尝试使用渲染和重新渲染功能。重新渲染函数只会渲染已更改的父级 DOM 部分(parent-markup 以下的所有内容)。
render: function () {
//render everything below .parent
}
rerender: function () {
//render stuff below parent-mark-up
}
HTML可以拆分
<div class="parent">
<div class="parent-markup"></div>
<div class="children"></div>
</div>
如果你确实需要渲染整个父元素并想重用子元素 DOM 你可以只保护 el 然后再次附加它,之后使用 this.delegateEvents();
来确保 Events a又被冒泡了。
一般我会把监听器放在初始化函数中,推荐使用this.listenTo(this.childCollection , 'add', this.callback);
Backbonejs: .on vs .listenTo vs .bind
最后我建议使用像这样的模块化语法
var RowView = Backbone.View.extend({
initialize: function(options) {}
render: function() {}
});
更新:这是一个fiddle:https://jsfiddle.net/gs4r8k10/30/
您可以使用 jQuery detach()
分离现有子项 DOM 并在父项 re-renders 之后再次附加它们。
如果可以像
if(this.childrenAlreadyRendered){
// special performant rendering with detach
}
在您的 render
方法中。 marionette 做这样的智能渲染。