Dojo垃圾收集/资源解放技术?

时间:2012-04-27 17:57:10

标签: dojo

我最近创建了我认为是基于页面的应用程序,它现在被嵌入作为控件使用。 “控制”需要多次卸载/重新加载。这会导致订阅和未被销毁的dijit控件出现问题。我已经找到了必要的断开连接,注册表.detroy逻辑,但它很乏味。是否有任何最佳实践可以使控件集合具有可销毁性?

以下示例代码显示了基本逻辑可以完成的任务: http://pastebin.com/bUUBUMP9

我在问一个框架是否存在类似于AppDomain的框架,在该框架中可以清除在该上下文中创建的任何内容。类似于在IFRAME中嵌入控件......但不是。

2 个答案:

答案 0 :(得分:4)

我可以看到两种让您的生活更轻松的做法:

  1. Dijit小部件扩展dijit/_WidgetBase,因此小部件提供(dis)connect(un)subscribe方法。在连接小部件时,您应该使用它们而不是通用aspect.connect()topic.subscribe(),因为这样小部件会在销毁时自动断开取消订阅,所以你不必。

  2. 通过dijit/layout整理您的小部件,例如使用dijit/layout/ContentPane而不是将小部件放入DOM中,因为这样您只需要在destroyRecursive()上调用ContentPane,它就会正确地销毁它的所有子节点。根据您的需要嵌套容器,以获得适当的粒度和视觉吸引力(这与Java JPanel的概念相同)。

  3. 应用上述原则,您可能只需要在层次结构中最高的容器上调用destroyRecursive()来销毁dijits。

答案 1 :(得分:0)

phusick提供的答案更好,但在这种情况下并不是真正的选择。我提出了这样的解决方案:

var dcHandles = [], dsHandles = [], dc = dojo.connect, ds = dojo.subscribe;

dojo.connect = function () {
    var h = dc.apply ( dojo, arguments );
    dcHandles.push ( h );
    return h;
};

dojo.subscribe = function () {
    var h = ds.apply ( dojo, arguments );
    dsHandles.push ( h );
    return h;
};

dojo.subscribe ( "unload", function () {    
    // restore dojo methods
    dojo.connect = dc;
    dojo.subscribe = ds;

    var w, mll;

    mll = dojo._windowUnloaders;
    while (mll.length) {
        ( mll.pop () ) ();
    }

    if ( dijit.registry ) {
        w = dijit.byId ( "topLevelItem1" );
        w && w.destroyRecursive ();
        w = dijit.byId ( "topLevelItem2" );
        w && w.destroyRecursive ();

        // destroy any other wijits
        dijit.registry.forEach ( function ( w ) {
            try
            {
                w.destroyRecursive ();
            }
            catch ( ex )
            {
                $.error ( ex );
            }
        } );
    }

    dojo.forEach ( dcHandles, function ( h ) {
        dojo.disconnect ( h );
    } );

    dojo.forEach ( dsHandles, function ( h ) {
        dojo.unsubscribe ( h );
    } );

   // reset monad-like values
    my.global.values.value1 = null;

    dcHandles = [];
    dsHandles = [];


} );

上面给了我一些保证,即在不改变大量代码的情况下,所有内容都会被取消注册/销毁/取消引用。