2012-04-27 5 views
5

Ich habe vor kurzem erstellt, was ich dachte, war eine seitenbasierte Anwendung, die jetzt als Steuerelement eingebettet verwendet wird. Die 'Steuerung' muss mehrmals entladen/neu geladen werden. Dies führt zu Problemen mit Abonnements und Dijit-Steuerelementen, die nicht zerstört wurden. Ich habe die notwendige Disconnect, Registry.Destroy Logik ausgearbeitet, aber es ist mühsam. Gibt es Best Practices, um eine Sammlung von Steuerelementen zerstörbar zu machen?Dojo Müllabfuhr/Ressourcenfreigabe Techniken?

Hier ist Beispielcode zeigt, was mit einfacher Logik durchgeführt werden kann: http://pastebin.com/bUUBUMP9

Ich frage, ob ein Rahmen in einem AppDomain analog liegt vor, wenn irgendetwas in diesem Zusammenhang erstellt wird, kann bis zu reinigen. Ähnlich dem Einbetten des Steuerelements in einen IFRAME ... aber nicht.

Antwort

4

kann ich zwei Praktiken sehen, die Ihr Leben einfacher machen:

  1. Dijit Widgets erweitern dijit/_WidgetBase und damit ein Widget bietet (dis)connect und (un)subscribe Methoden. Sie sollten sie anstelle von allgemeinen Zweck verwenden aspect.connect() und topic.subscribe() bei der Verdrahtung Widgets, weil auf diese Weise das Widget trennt und automatisch abmelden wenn zerstört wird, so dass Sie nicht müssen.

  2. Organisieren Sie Ihre Widgets über dijit/layout, z. Verwenden Sie dijit/layout/ContentPane anstelle Widgets nur in das DOM zu platzieren, denn auf diese Weise müssen Sie destroyRecursive() nur auf die ContentPane aufrufen und es wird ordnungsgemäß alle seine Kinder zerstören. Ordnen Sie Container entsprechend Ihren Anforderungen an, um die richtige Granularität und visuelle Attraktivität zu erzielen (dasselbe Konzept wie Javas JPanel).

die oben genannten Grundsätze anwenden können Sie nur destroyRecursive() auf den Behälter höchste in der Hierarchie anrufen müssen Dijits zu zerstören.

0

Die Antwort von phusick ist besser, war aber in diesem Fall keine Option. Ich kam mit einer Lösung wie folgt auf:

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 = []; 


}); 

Die oben gab mir eine gewisse Sicherheit, dass alles wird deregistrieren/zerstört/dereferenzierte ohne viel Code zu ändern.