2011-01-07 11 views
8

Mein Inhalt wird durch Ajax ersetzt, aber manchmal hat ein Element dieselbe ID auf zwei Seiten (dh ein Foto auf der Homepage hat dieselbe ID auf der Galerieseite). Dies bedeutet, dass, wenn dojo.parser.parse genannt wird, werden die Widgets versuchen, erneut hinzugefügt werden, und die folgenden Fehler ausgelöst:dojo: zerstöre alle Widgets durch dom node

Error: Tried to register widget with id==____ but that id is already registered 

Idealerweise, was ich möchte ist zu tun, laufen destroyRecursive auf die DOM-Knoten, den der AJAX ersetzt. Ich habe sowohl die unten versucht, aber weder Arbeit (ich glaube destroyRecursive für Widgets nicht DOM ist?):

dojo.byId('main').destroyRecursive(); 
dijit.byId('main').destroyRecursive(); 

Gibt es ein guter Weg, dies zu tun, oder muss ich versuchen und sicherzustellen, dass alle meine IDs sind anders?

Antwort

22

Sie befinden sich auf dem richtigen Weg, und Sie haben Recht, dass destroyRecursive nur auf Widgets existiert. Es gibt jedoch einige Möglichkeiten, um das zu erreichen, was Sie tun möchten.

Wenn Sie Widgets in nennenswertem Umfang verwenden und das betreffende div regelmäßig als Bucket zum Speichern von Inhalten einschließlich Widgets verwendet wird, dann empfehle ich Ihnen einen Blick auf dijit.layout.ContentPane. ContentPane ist ein Widget, das sich hauptsächlich auf die Idee eines Containers konzentriert, der Inhalte entweder direkt oder von einer URL empfängt, die Widgets enthalten kann oder auch nicht.

Gerade jetzt sind Sie wahrscheinlich so etwas wie dies auf jeder Seite ändern zu tun:

dojo.xhrGet({ 
    url: 'something.html', 
    load: function(html) { 
     dojo.byId('main').innerHTML = html; 
     dojo.parser.parse(dojo.byId('main')); 
    } 
    error: function(error) { ... } 
}); 

Mit einem ContentPane, könnte man das Gleiche tun, wie folgt:

cp.set('href', 'something.html'); //use attr instead of set if < dojo 1.5 

Damit ContentPane wird nicht nur diese URL abrufen und ihren Inhalt behalten - sie analysiert auch alle darin enthaltenen Widgets - und ebenso wichtig, dass sie automatisch alle vorhandenen Widgets in sich selbst zerstört, bevor sie ihren Inhalt ersetzt.

Sie können im Dojo Dokumentation mehr darüber lesen:

Alternativ, wenn Sie wie mit einem Widget nicht das Gefühl, Ihre Inhalte zu halten, Sie kann nach Widgets in deinem div suchen und sie selbst zerstören. Hier ist der einfachste Weg, es zu tun:

dojo.forEach(dijit.findWidgets(dojo.byId('main')), function(w) { 
    w.destroyRecursive(); 
}); 
+0

Große Antwort dank – Ashley

+0

+1 wirklich guter Anwendungsfall für ContentPane –

+2

AMD stellt fest: dojo.forEach - Import "Dojo/_base/array", wie Array, dann Array.ForEach mit | dijit.findWidgets - Import "Dijit/Registrierung" dann mit Registry.FindWidgets – Deejers

4
dojo.query('selector').forEach(function(node){ 
    dijit.byNode(node).destroyRecursive(true); 
}); 

Grundsätzlich Auswahl der Knoten ... Sie können das als Widget-Objekt abgebildet erhalten durch dojo.byNode(node) verwenden und dann destroyRecursive(true);

0

löste ich ein ähnliches Problem , Löschen einfach aus der Registrierung mit dijit.registry.remove ('idName') nach dem Entfernen des Inhalts mit destroyRecursive (false), vor dem Neuladen.

if(typeof registry.byId("tableOfContents") != "undefined"){ 
     registry.byId("tableOfContents").destroyRecursive(false); 
     dijit.registry.remove('tableOfContents'); 
    } 
0

Wenn Sie mehr als ein Widget auf einer Seite zerstört haben, funktioniert die folgende Lösung für mich.

var widg = dijit.findWidgets(dojo.byId('root-id')); // root-id is top div id which encloses all widgets 
$(widg).each(function(){ 

    dijit.byId($(this).attr("id")).destroy(true); 

    });