在backbone中管理视图的模式

20

从GWT过来,Backbone似乎缺少一个内置的解决方案来处理视图的生命周期。在GWT中,每个activity(与Backbone中的View几乎等同),都由ActivityManager管理,该管理器调用activity的onStart / onStop方法,传递eventBus和可以呈现Activity的元素。 在停止时,ActivityManager将取消绑定活动已绑定到事件总线的所有事件,并从DOM中删除视图。

在Backbone中,很容易将事件绑定到模型和集合,但您必须手动删除它们,并且没有通用的API方法可供使用。

因此,我正在寻找最佳实践模式,以管理视图以确保不会监听无关的事件而被杀死或禁用。

4个回答

13

你说得对,目前还没有内置的解决方案。

不过,当然可以扩展 Backbone 以提供这个功能,Derick Bailey 最近写了一篇关于这方面的博客文章。

可以看一下这里: http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/

这绝不是圣杯,你可以自由实现,但这是一个非常简单直接的方法,用于处理“僵尸”视图,现在,你仍然需要注意内存中的其他对象,但至少从视图方面来说,这是一个开始!


不错的文章。感谢提供链接。 - ProTom
是的,这篇文章方向正确,但最终视图负责清理。我正在寻找一种解决方案,其中视图不需要关心清理,因为有其他人在处理。考虑到更大的团队,有时会有人忘记手动清理。此外,您还必须一遍又一遍地编写相同的代码。 - Andreas Köberle
这样的系统在Backbone中不存在,因为他们想提供一个结构,既灵活又稳定。当然,有人可能已经考虑过这个问题,并开始开发插件,但我还没有听说过有一个可以自动完成所有这些功能的插件(至少目前还没有)。 - Sander
在这篇文章中,Derek通过一个close()方法扩展了Backbone View原型,该方法将解除所有事件绑定并从视图中删除元素。只需让用户使用view.close()而不是view.remove(),然后他们就可以忘记清理工作了。 - Eric Hu
请使用 @EricHu 或者扩展 view.remove(可以是 Backbone View 或您自己的 BaseView)。 - roberkules

5

我正在使用自定义的BaseView,它扩展了Backbone的remove方法:

app.BaseView = Backbone.View.extend({

    views: [], // array to keep a ref of child-views for proper disposal later on

    remove: function() {

        // dispose any sub-views
        _.each(this.views || [], function(view) {
            view.remove();
        });

        // if the inheriting class defines a custom on-remove method, call it!
        _.isFunction(this.onRemove) && this.onRemove();

        // unbind all events from this view
        this.off();

        // finally, call Backbone's default remove method to
        // remove the view from the DOM
        Backbone.View.prototype.remove.call(this);
    }
}

不过需要注意的是:模型和集合需要手动释放,因为你不知道它是否被其他视图使用。


3

2
我将我的解决方案发布在 https://github.com/thomasdao/Backbone-View-Manager上,用于管理视图。
视图管理器在创建新视图之前,始终清理现有的视图。现在我会通过以下方式初始化一个新的视图:
newView = VM.createView("newView", function(){
             return new View();
          };

如果我想重用一个视图而不是创建一个新的,我可以使用

newView = VM.reuseView("newView", function() {
              return new View();
          }

VM.reuseView 和 VM.createView 的区别在于,reuseView 会查找名称为 "newView" 的现有视图,如果找到就返回给你,否则它将执行回调函数并缓存结果。VM.createView 将始终执行回调函数并清除现有视图。因此,如果视图是动态的且经常更改,则可能喜欢使用 VM.createView。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接