使用backbone.js更新已更改的属性

时间:2011-09-16 11:32:35

标签: javascript backbone.js backbone-model

所以我正在设置一个具有更新属性的模型。

然后在我看来,我正在听这个模型的变化事件。

当发生火灾时我想我应该使用model.changedAttributes?我是否通过回调?

它应该返回所有已更新或新的属性的哈希值?反正知道哪些是更新的,哪些是新的?

如果我有更改属性的哈希,我该如何进行更新?将对象解析为属性类型,还是应该从get go使用更高分辨率的侦听器?

谢谢!

2 个答案:

答案 0 :(得分:31)

如果您的视图仅显示单个属性 - 例如,如果它是显示模型的某个布尔属性的复选框 - 您应该听取该属性的'change:attribute_name'事件,如{{3}中所述}。

如果您的视图更复杂并且依赖于多个模型属性 - 例如,如果它是具有“完成”,“文本”和“dueDate”元素的“待办事项”列表项的视图,那么请听取'改变'事件。在这种情况下,您可以选择更新每个事件的所有元素,也可以使用changedAttributes()来确定哪些元素需要更新。

说明......

使用'change:attribute_name'事件更新属性:

这种样式适用于简单视图,其中呈现的模型属性的数量是< 3左右。不仅如此,代码变得有点麻烦。

model.bind('change:done', function() {
    view.doneElement.checked = model.get('done');
});
model.bind('change:text', function() {
    view.textElement.value = model.get('text');
});
model.bind('change:dueDate', function() {
    view.dueDateElement.value = model.get('dueDate');
});

更新“更改”事件的所有内容:

这种风格适用于渲染4个或更多属性的复杂视图(3/4属性计数只是一个粗略的指导方针,主要基于我个人的观点)。

model.bind('change', function() {
    view.doneElement.checked = model.get('done');
    view.textElement.value = model.get('text');
    view.dueDateElement.value = model.get('dueDate');
});

这样做的缺点是,对于任何更改,视图的每个元素都会更新。因此,例如,如果某人将待办事项标记为“已完成”,则该文本将被重新呈现,可能会丢失他们可能在那里进行的任何选择。有时这种事情是一个问题,有时候不是 - 你必须根据你的观点到底做出决定。

仅更新自上次“更改”事件以来发生的更改:

这是上述细微差别的变化,并结合了两种方法的优点。它根据changedAttributes()结果更新需要更新的视图元素。

model.bind('change', function() {
  var diff = model.changedAttributes();
  for (var att in diff) {
    switch(att) {
      case 'done':
        view.doneElement.checked = model.get('done');
        break;
      case 'text':
        view.textElement.value = model.get('text');
        break;
      case 'dueDate':
        view.dueDateElement.value = model.get('dueDate');
        break;
    }
  }
});

最后,我会注意到,还有另外一个变体,即让视图存储它显示的值的散列,并将其传递给changedAttributes()方法。这通常没有必要,所以我不会在这里向你详细说明。

答案 1 :(得分:0)

根据backbone docs,change事件将模型和模型的集合传递给事件处理程序。

事件在发生更改后触发,因此传递的模型包含更改。

“更改”事件不允许您知道哪些属性已更改或已添加。如果您需要根据各个属性进行操作,请使用“更改:属性”事件。