My content is replaced with ajax but sometimes an element will have the same id on two pages (ie, a photo on the home page has the same id on the gallery page). This means that when dojo.parser.parse is called, the widgets are trying to be re-added, and the below error is thrown:
Error: Tried to register widget with id==____ but that id is already registered
Ideally, what I'd like to do is run destroyRecursive on the DOM node that the AJAX replaces. I've tried both of the below but neither work (I believe destroyRecursive is for w开发者_运维知识库idgets not DOM?):
dojo.byId('main').destroyRecursive();
dijit.byId('main').destroyRecursive();
Is there a good way of doing this, or do I need to try and ensure that all my id's are different?
You are on the right track, and you are correct that destroyRecursive only exists on widgets. However, there are a couple of choices to accomplish what you want to do.
If you're using widgets to a significant extent, and the div in question is regularly being used as a bucket to hold content including widgets, then I would highly recommend you have a look at dijit.layout.ContentPane
. ContentPane is a widget primarily focused around the idea of a container that receives content, either directly or from a URL, which may or may not include widgets.
Right now you're probably doing something like this on each page change:
dojo.xhrGet({
url: 'something.html',
load: function(html) {
dojo.byId('main').innerHTML = html;
dojo.parser.parse(dojo.byId('main'));
}
error: function(error) { ... }
});
With a ContentPane, you could do the same thing like this:
cp.set('href', 'something.html'); //use attr instead of set if < dojo 1.5
With this, ContentPane will not only fetch that URL and hold its contents - it will also parse any widgets within it - and equally importantly, it will automatically destroy any existing widgets within itself before it replaces its content.
You can read more about it in the Dojo documentation:
- http://dojotoolkit.org/reference-guide/dijit/layout/ContentPane.html
- http://dojotoolkit.org/api/dijit/layout/ContentPane
Alternatively, if you don't feel like using a widget to hold your content, you can look for widgets in your div and destroy them yourself. Here's the easiest way to do it:
dojo.forEach(dijit.findWidgets(dojo.byId('main')), function(w) {
w.destroyRecursive();
});
dojo.query('selector').forEach(function(node){
dijit.byNode(node).destroyRecursive(true);
});
Basically, selecting the node... You can get the mapped as widget object by using dojo.byNode(node)
, and then destroyRecursive(true);
I solved a similar problem, simply deleting from registry using dijit.registry.remove('idName') after eliminating the content with destroyRecursive(false), before Reloading it.
if(typeof registry.byId("tableOfContents") != "undefined"){
registry.byId("tableOfContents").destroyRecursive(false);
dijit.registry.remove('tableOfContents');
}
If you have more than one widget to be destroyed on a page, the following solution works for me.
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);
});
精彩评论