2011-01-07 3 views
8

Мой контент заменяется на ajax, но иногда элемент будет иметь один и тот же идентификатор на двух страницах (то есть, фотография на главной странице имеет тот же идентификатор на странице галереи). Это означает, что, когда dojo.parser.parse называется, виджеты пытаются быть повторно добавлен, а ниже ошибка возникает:dojo: уничтожить все виджеты dom dom

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

В идеале я хотел бы сделать, это запустить destroyRecursive на DOM, который заменяет AJAX. Я попробовал оба ниже, но ни работы (я считаю, destroyRecursive для виджетов не DOM?):

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

Есть хороший способ сделать это, или мне нужно попробовать и убедиться, что все мои id - разные?

ответ

22

Вы на правильном пути, и вы правы, что destroyRecursive существует только в виджетах. Тем не менее, есть несколько вариантов, чтобы выполнить то, что вы хотите сделать.

Если вы используете виджеты в значительной степени, а вопрос, который находится в вопросе, регулярно используется в качестве ведра для хранения содержимого, включая виджеты, то я настоятельно рекомендую вам взглянуть на dijit.layout.ContentPane. ContentPane - это виджет, в первую очередь ориентированный на идею контейнера, который получает контент, либо напрямую, либо из URL-адреса, который может включать или не включать виджеты.

Прямо сейчас вы, вероятно, делать что-то вроде этого на каждой смене страницы:

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

С в ContentPane, вы могли бы сделать то же самое, как это:

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

с этим, ContentPane будет не только извлекать этот URL-адрес и содержать его содержимое - он также будет анализировать любые виджеты внутри него - и, что не менее важно, он автоматически уничтожит любые существующие виджеты внутри себя, прежде чем он заменит его содержимое.

Вы можете прочитать об этом в документации Dojo:

В качестве альтернативы, если вы не чувствуете, как с помощью виджета, чтобы держать ваше содержание, вы могут искать виджеты в вашем div и уничтожать их самостоятельно. Вот самый простой способ сделать это:

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

Великий ответ, спасибо – Ashley

+0

+1 действительно хороший случай использования для ContentPane –

+2

отмечает AMD: dojo.forEach - импорт "додзё/_Образы базовой/массив" в виде массива, а затем с помощью array.forEach | dijit.findWidgets - импортировать «dijit/registry», а затем использовать registry.findWidgets – Deejers

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

В принципе, выбирая узел ... Вы можете получить отображенный как объект виджета с помощью dojo.byNode(node), а затем destroyRecursive(true);

0

я решил аналогичную проблему , просто удалив из реестра с помощью dijit.registry.remove ('idName') после удаления содержимого с помощью destroyRecursive (false) перед перезагрузкой.

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

Если у вас есть несколько виджета для уничтожения на странице, для меня работает следующее решение.

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); 

    });