Backbone.js:总是检测模型何时有属性集,而不是/只是/更改

Backbone.js: Always detect when a model has an attribute set, not /just/ changed

本文关键字:更改 属性 只是 js 检测 何时 模型 Backbone      更新时间:2023-09-26

在Backbone中,当我将Model的属性设置为与以前相同的值时,不会触发"更改"事件。

我的观点:

initialize: function() {
  this.$lastRollResult = this.$el.find('#lastRollResult');
  this.listenTo(this.model, 'change:lastRoll', this.render);
},
render: function() {
  this.$lastRollResult
    .html(this.model.get('lastRoll'))
    .addClass('shaking');
  var self = this;
  setTimeout(function() {
    self.$lastRollResult.removeClass('shaking');
  }, 1000);
},
events: {
  'click #button': function() {
    this.model.set('lastRoll', getRandomInteger(1, 6));
  }
}

有时,当我调用getRandomInteger()时,int将与上一个相同,导致我的.set('lastRoll',int)没有注册为"更改"事件。但这意味着我的"摇晃"课程不会被应用,这很糟糕。

如何使Backbone始终识别何时设置了属性,即使我设置的值相同?是否存在某种"设置"事件?(在文档中没有看到。)

编辑:我知道可能有一种{silent:true}/.trigger()破解方法可以实现这一点,但有没有任何"干净"或"语义"的方法可以始终识别.set()调用?

我认为你的设计是错误的。视图不应该选择一个随机数并告诉模型这是它的新值,视图应该告诉模型汇总一个新数字。然后你可以在你的模型中有这个:

roll: function() {
    this.set('lastRoll', getRandomInteger(1, 6), { silent: true });
    this.trigger('change:lastRoll', this, this.get('lastRoll'));
}

而您的视图只是CCD_ 1。是的,你仍然会做{silent:true}trigger破解,但至少它会在正确的地方。

当然,这可能会有奇怪的副作用,所以你可以在设置新的值之前悄悄地取消设置模型的值:

roll: function() {
    // I suppose you could quietly unset here if you feel bad
    // about fiddling with `attributes`.
    this.attributes.lastRoll = null;
    this.set('lastRoll', getRandomInteger(1, 6));
}

同样,在模型上有一个单独的roll方法是向外部世界隐藏所有这些欺诈行为的一种方便方法。