在Backbone.js中,为什么静默更改最终会触发更改事件?

26
当我在设置Backbone模型的属性时,传递{"silent":true}参数时,为什么不只是抑制change:attribute事件?下次更改属性时触发该事件的优点是什么?
更新
Backbone 0.9.10更改了传递{"silent":true}参数的行为。来自变更日志的内容如下:
传递{silent:true}将不再延迟单个“change:attr”事件,而是完全静音。
浏览变更日志here
2个回答

30
这个问题也困扰了我一段时间。
原因是 {silent:true} 并不意味着“一切照常,只是不触发事件”。
根据 @jashkenas 的各种评论和答案,它似乎意味着“仅更改属性值(并将其添加到'changedAttributes'哈希表中),但推迟所有其他“与更改相关”的活动直到以后。”
'silent' 不会阻止那些属性的 change 事件,它只是将 'announcement' 排队,直到下一个 change 事件被触发。
因此,它可能更好地命名为 defer相关信息:

https://github.com/documentcloud/backbone/pull/850

“静默”变更的意义在于,从模型的角度来看,它并不被视为一种变更。稍后,当实际发生变更时,您将一次性获得全部差异。

https://github.com/documentcloud/backbone/issues/870

因为静默更改的目的是允许您在不实际进行更改的情况下暂时调整模型的内部状态。稍后,当属性实际更改时,验证运行并发出事件。在进行静默更改时发出错误事件是没有意义的。
更新4/7/2013
注意:我尚未测试此以确认行为,这仅基于我对发布说明的阅读...
从Backbone 0.9.10开始,上述行为已更改。在该版本(及更高版本)中,silent:true完全抑制change:attr事件-而不仅仅是延迟它们。

http://backbonejs.org/#changelog


有趣。我想通常情况下我想传递“silent:true”的原因是为了防止调用更改事件处理程序。我想知道这是否是其他人能够处理的常见情况? - stinkycheeseman

2
在backbone 0.9.2中,set函数在更新任何更改之前运行验证。
  // Run validation.
  if (!this._validate(attrs, options)) return false;

如果传递了{silent: true}选项,则不会执行验证代码。

  if (options.silent || !this.validate) return true;

这意味着model.set({value: 100}, {silent: true});能够将“无效”的值设置到模型中,因此属性会被更新,但更改事件不会触发。

当您想要更新某个字段并防止整个模型验证时,这非常有用,因此如果模型尚未完成,则仍会传播更改到属性。但通常您也希望视图显示更改,因此您必须手动调用model.change()model.trigger('change:value', model, value)


我想强调,完全将验证和触发更改事件分开是可以的。在我的小部件中,当用户用鼠标离开小部件时(失去焦点),不进行验证(只有通过TAB或ENTER键才进行验证),但我会保存更改后的值,并希望在此发生时得到通知(触发更改事件),以便对其做出反应。 - Wolfgang Adamec

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接