如果多个模型属性同时更改,是否可以只收到一次通知?

Is it possible to get notified only once if several model attributes change simultaniously?

我想要一个 Marionette ItemView(或 LayoutView),它会在模型​​更改时重新呈现。它实际上很容易实现:

modelEvents: {
  'change': 'render'
}

但是,并非每个视图都显示模型的每个属性。所以我有了一个想法,通过只监听那些改变了一些属性的事件来减少重新渲染的次数。如果视图只需要一个属性,情况也很简单:

modelEvents: {
  'change:attribute': 'render'
}

但是比较复杂,如果需要监听多个属性的变化。两者

modelEvents: {
  'change:attribute1': 'render',
  'change:attribute2': 'render'
}

modelEvents: {
  'change:attribute1 change:attribute2': 'render'
}

如果 attribute1 和 attribute2 在一个事件中都被更改,将重新渲染视图两次。有什么简单的语法可以在这种情况下只通知一次吗?我知道,我可以做到:

modelEvents: {
  'change': 'checkIfRenderNeeded'
},
checkIfRenderNeeded: function(event) {
  if (('attribute1' in event.changed) || ('attribute2' in event.changed)) {
    this.render();
  }
}

但是有没有更优雅的解决方案呢?也许一些特殊的语法可以在 modelEvents 属性 中包含此行为,而不必在通用更改事件侦听器上编写更改检查器?

我不熟悉marionette,但我会从我自己的经验中抽取一页。

设置一个函数作为渲染的前端。所有渲染尝试都通过此函数。此函数管理一个计时器,该计时器在完成时触发渲染函数。每当调用该函数时,它都会清除计时器,因此不会有排队的请求进行渲染。然后它会重置计时器。

与 Paul Rowe 相同的解决方案,但在 Marionette 的上下文中:

您可以使用 Underscore 的 _.debounce 函数来包装您的 render 函数:

var lazyRender = _.debounce(render, 50)

modelEvents: {
  'change:attribute1 change:attribute2': 'lazyRender'
}

然后,如果 attribute1attribute2 在 50 毫秒的时间跨度内发生多次变化,lazyRender 将被调用多次,但 render 函数只会调用一次。