【问题标题】:Backbone JS: how to disable sync for delete?Backbone JS:如何禁用同步删除?
【发布时间】:2012-04-30 09:45:56
【问题描述】:

我正在处理一个线程化的 cmets 集合,当我删除一个有孩子的评论时,我为此评论执行 model.destroy(),并且在服务器端它的所有分支都被删除。

我编写了一个函数,一旦从树中删除一个节点,就会查找所有孤立节点并将它们也删除。所以当我找到孤儿时,我也会在它们上运行model.destroy(),但因为它们已经在服务器上删除,同步返回错误。

有没有办法为某些destroy() 调用禁用同步?

【问题讨论】:

  • 我很好奇覆盖 .sync() 并为 delete 方法添加一些额外的逻辑是否会过大,或者是否有更清洁的方法。
  • 好吧,我希望不要覆盖 .sync() 但我看不到任何原生方式。我可以通过触发“销毁”事件并从集合中拼接模型来破解,但这听起来不合理。

标签: model backbone.js destroy


【解决方案1】:

由于所有destroy 方法所做的只是发送删除请求并触发destroy,因此只需触发destroy 正是您要查找的内容。

model.trigger('destroy', model, model.collection, options);

是的,感觉有点骇人听闻,但这几乎就是 Backbone 代码所做的所有事情。如果您愿意,并且如果您有一个从中扩展的基本模型,则可以将其作为方法添加到该基本模型上,这样可能不会让人觉得很老套。

【讨论】:

  • 谢谢@Edward。我最终只是从集合中删除了它们。
  • @forresto - 如果模型仅在单个集合中,则有效。如果您的模型是多个集合,则您必须知道模型在哪些集合中并对每个集合执行此操作 - 这意味着在模型中跟踪它属于哪些集合。这有点倒退。通过触发模型上的“销毁”,它所在的任何集合都会将其删除,您不必跟踪模型所在的集合。
  • @EdwardMSmith 调用 model.trigger('destroy') 还不够吗?是否需要传递model、model.collection和options参数?谢谢你的回答。
  • 其实从主干源来看,在触发destroy事件之前还有一个this.model.stopListening();。然后,destroy事件会触发collection.remove()函数。
【解决方案2】:

这有点晚了,但可以作为其他有同样问题的人的替代解决方案。

面对一个非常相似的问题,我最终将所有子 ID 设置为 null,然后再调用 destroy。这样,骨干网认为它们是新的,并且不会在删除时向服务器生成DELETE HTTP 请求。

deleteParent: function() {
  this.model.children.each(function(child) {
    // Set to null so that it doesn't try to spawn a 'DELETE' http request 
    // on 'destroy' since thinks its new (hack).
    child.id = null; 
    child.destroy();
  });
  // This one DOES result in a 'DELETE' http request since it has an ID.
  this.model.destroy();
},

【讨论】:

  • 那么在不从服务器上实际删除的情况下进行销毁的目的是什么?
  • 如果我正确理解了您的问题,当您从服务器中删除父级时,您也删除了它的所有子级(可能在事务中),所以当您删除 (destroy ) UI 中的子孤儿,您不想调用服务器来删除每个孤儿,因为它们不再存在。这实现了所需的行为。
【解决方案3】:

遇到了同样的问题。

使用模型指向其包含集合的链接从该集合中删除模型是我的首选解决方案,因为这正是我想要做的并且在代码中非常清楚:

// From the view
this.model.collection.remove(this.model);

【讨论】:

  • 虽然这会从集合中删除模型,但这不会触发销毁事件,如果您有任何事件监听它,可能会导致问题。
【解决方案4】:

基于 fcarriedo 的回答,只需覆盖模型声明中的 destroy 方法:

Models.YourModelName = Backbone.Model.extend({
    destroy: function () {
        this.id = null;
        Backbone.Model.prototype.destroy.apply(this, arguments);
    }
});

【讨论】:

    【解决方案5】:

    这允许您尊重销毁调用,包括任何成功处理程序

    Backbone.Model.extend({
        destroy: function (options) {
           // don't make a server call, just delete from collection and call success
           this.trigger('destroy', this, this.collection, options);
           if (options && options.success) {
                  options.success();
           }
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-27
      • 1970-01-01
      • 1970-01-01
      • 2017-01-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多