在以下代码中,
this.listenTo(this.model, 'change:voteCount', this.changeVoteCount);
this.listenTo(this.model, 'change', this.renderTemplate);
如果“voteCount
”属性更新,我想触发“this.changeVoteCount
”方法,但不会触发“this.renderTemplate
”。
我已经谷歌搜索大约2个小时,无法找到解决方案。我该怎么办?
(只是为什么我选择@ try-catch-finally回答的解释)
对于同样遇到这个问题的人,我想清除混淆应该选择哪个答案作为解决方案。
我将描述一些细节来解释为什么我选择这个答案。以下是我的模型结构:
{
'name': 'some string',
'location': 'some string',
'link': 'some string',
'voteCount': 0 }
否则“voteCount
”属性已更新,我想触发“更改”事件绑定方法(在我的情况下为this.renderTemplate
)。
所以我尝试了第一种方法,
this.listenTo(this.model, 'change:name change:location change:link', this.renderTemplate);
在这种方法中,如果我在一个地方同时更新“location
”和“name
”,那么this.renderTemplate
方法将触发两次。每当“this.renderTemplate
”,“location
”或“name
”属性单独更新或同时更新时,我希望link
方法触发一次。
最后,我尝试了以下方法并取得了成功。
this.listenTo(this.model, 'change', function(model) {
if (_.isEmpty(_.intersection(_.keys(model.changed), ["voteCount"]))) {
this.renderTemplate.apply(this, arguments);
}
});
答案 0 :(得分:2)
如果您不想在每个参数更改时进行渲染,您可以指定哪些参数应该触发渲染。
this.listenTo(this.model, 'change:param1 change:param2', _.debounce(this.renderTemplate));
修改:如果您不想在多个字段上多次渲染更改,则可以使用下划线debounce:
b
如果在短时间内多次调用它,它将只调用一次渲染。
答案 1 :(得分:2)
除了列出您想要听取@antejan提到的更改的所有属性之外,您也可以以编程方式执行此操作。
这样您就可以检查模型的changed
属性,其中包含所有已更改的属性。
this.listenTo(this.model, 'change', function(model) {
if (!_.contains(_.keys(model.changed), "voteCount") {
this.renderTemplate.apply(this, arguments);
}
});
将多个键列入黑名单时,您也可以这样做:
if (_.isEmpty(_.intersection(_.keys(model.changed), ["attr1", "attr2", ...])) { ...
只要你的模型只有一些属性,我就更喜欢@antejans明确列出所有属性的方式,因为它更清晰了:
this.listenTo(this.model, "change:attr1 change:attr2 ...", this.renderTemplate);
请注意,列出多个change:attr
事件可能会导致性能下降,因为Backbone会在for
循环中调用侦听器。请参阅set()
的{{3}}:
...
if (!silent) {
if (changes.length) this._pending = options;
for (var i = 0, l = changes.length; i < l; i++) {
this.trigger('change:' + changes[i], this, current[changes[i]], options);
}
}
// You might be wondering why there's a `while` loop here. Changes can
// be recursively nested within `"change"` events.
if (changing) return this;
if (!silent) {
while (this._pending) {
options = this._pending;
this._pending = false;
this.trigger('change', this, options);
}
}