Backbone.js`model.destroy()`自定义转换?
当我使用Backbone的model.destroy()
,它似乎会自动从DOM中删除该视图。
有没有办法让我使用destroy()
发送DELETE请求,但是自己从DOM中删除视图?
就像是:
this.model.destroy({ wait: true, success: function(){ $('#myElement').animate({ "height" : "0", 1000, function(){$('#myElement').remove()} }); } });
您需要在包含项视图( 文档 )的Collection视图中覆盖_onCollectionRemove()
)。 这是从模型中删除模型时调用的函数,它也是破坏视图的内容。 具体来说,你如何选择覆盖它取决于你,但用动画函数覆盖它可能是最容易的,也许沿着以下几行……
_onCollectionRemove: function(model) { var view = this.children.findByModel(model); var that = this; view.$('#myElement').animate({ "height" : "0", 1000, function(){ that.removeChildView(view); that.checkEmpty(); } }); }
如果您希望在destroy
回调中手动删除视图,只需覆盖_onCollectionRemove()
以包含空函数,并在删除请求的回调中执行您想要的任何操作。 我推荐上面描述的方法,而不是在你的destroy
回调中做到这一点。 完全消除该function,然后在代码中的其他地方处理它的职责会干扰Marionette的预期事件流程。 简单地使用不同的UI效果覆盖该function可以保留自然流动。
编辑 :另一个用户以前的答案(现在由于downvoting而被删除)表明在UI效果完成后调用destroy
可能是明智的。 这不是一个很好的方法,因为OP指出 – 如果destroy
方法出现问题,(例如,如果远程服务器出现故障),用户看起来好像模型已被删除(UI效果已经完成)即使服务器无法访问,模型仍然存在。
提到的onBeforeDestroy方法对我不起作用。 它会在骨干网中抛出错误(删除删除方法)我的解决方案具有相同的方法,并且在itemView中运行良好
remove: function(){ this.$el.animate({"height" : "0"},500, function(){ $(this).remove(); }); },
我们可以专注于视图生命周期,而不是专注于模型事件。 为此,Marionette在Marionette.View上提供onBeforeDestroy
回调(由所有Marionette视图扩展)。 在ItemView中,您可以像这样定义回调
onBeforeDestroy: function () { $('#myElement').animate({ "height" : "0", 1000 }); }
他们是一个重要的警告 。 由于$.animate
是一个异步函数,因此在$.animate
完成转换之前可能会删除该视图。 因此,我们必须对onBeforeDestroy
进行修改。
onBeforeDestroy: function () { var animationDelay = 1000ms; this.remove = _.delay(_.bind(this.remove, this), animationDelay ); this.$el.animate({ "height" : "0", animationDelay }); }
基本上,我们在这里做的是将View.remove()
方法设置为在动画运行后触发,确保在this.remove
时,在动画运行后异步调用它。 我想你也可以用Promises做到这一点,但这需要更多的开销。
你需要使用以下之一:
- collection.remove模型
- collection.reset collection.model
每种方法都将重新渲染您的集合或复合视图。
使用js或jQuery直接从集合/复合视图中删除元素并不是一种好习惯。