javascript – 如何设置多个属性时限制数字更改事件?

我注意到当Backbone模型的多个属性设置如此
model.set({
    att1:val1,att2:val2
});

触发两个更改事件.我错误地认为在设置了所有属性后只会触发一个更改事件.

这似乎不是一个问题,但是当一个函数绑定到att1时也使用了att2的值.换句话说,当你这样做

model.bind('change:att1',func1);
...
func1 = function() {
    var att2 = model.get('att2');
}

变量att2将设置为模型属性att2的旧值.

问题是如何以优雅的方式防止这种情况.当然,一个选项是在设置att1之前设置att2或绑定到att2(而不是att1),但似乎这只是在简单情况下可行的选项.后一个选项还假设属性是按照set方法中列出的顺序设置的(​​我认为是这种情况).

我已多次遇到这个问题因此我的问题.问题是我花了一些时间才意识到实际发生了什么.

最后一点,就像你可以通过{silent:true}作为set方法一个选项一样,有一个选项{group:true}(或类似的东西)表示更改事件应该只是在设置了所有属性后触发.

解决方法

在更复杂的情况下,我会去自定义活动.

而不是绑定到更改:att1或更改:att2我会查找特定的自定义事件,在设置了要在模型上更改的所有属性后触发.

model.set({
    att1:val1,att2:val2
});
model.trigger('contact:updated'); // you can chose your custom event name yourself

model.bind('contact:updated',func1);
...
func1 = function() {
    var att2 = model.get('att2');
}

这个想法的缺点是你必须在想要触发事件的任何地方添加新的代码行.如果发生这种情况很多你可能想改变或覆盖model.set()来为你做,但是你已经在改变骨干代码,不知道你对此感觉如何.

编辑

在查看了主干的源代码之后,我注意到在更改后立即触发了更改事件:属性触发器. (由下面的snippit证明)

// Fire `change:attribute` events.
for (var attr in changes) {
  if (!options.silent) this.trigger('change:' + attr,this,changes[attr],options);
}

// Fire the `"change"` event,if the model has been changed.
if (!alreadyChanging) {
  if (!options.silent && this._changed) this.change(options);
  this._changing = false;
}

而this.change(选项);指这个:

change: function(options) {
  this.trigger('change',options);
  this._prevIoUsAttributes = _.clone(this.attributes);
  this._changed = false;
},

因此,如果您要绑定到更改事件而不是特定的change:argument事件,则在更改两个(或所有)属性后,您将到达回调函数.

唯一的缺点是,即使您更改了第三个或第四个属性,它也会触发任何更改.你需要计算…

它在jsfiddle http://jsfiddle.net/saelfaer/qm8xY/上如何工作的一个小例子

相关文章

前言 做过web项目开发的人对layer弹层组件肯定不陌生,作为l...
前言 前端表单校验是过滤无效数据、假数据、有毒数据的第一步...
前言 图片上传是web项目常见的需求,我基于之前的博客的代码...
前言 导出Excel文件这个功能,通常都是在后端实现返回前端一...
前言 众所周知,js是单线程的,从上往下,从左往右依次执行,...
前言 项目开发中,我们可能会碰到这样的需求:select标签,禁...