dojo:通过 dom 节点销毁所有小部件

Posted

技术标签:

【中文标题】dojo:通过 dom 节点销毁所有小部件【英文标题】:dojo: destroy all widgets by dom node 【发布时间】:2011-01-07 17:03:22 【问题描述】:

我的内容被 ajax 替换,但有时一个元素在两个页面上具有相同的 id(即,主页上的照片在图库页面上具有相同的 id)。这意味着当调用 dojo.parser.parse 时,正在尝试重新添加小部件,并引发以下错误:

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

理想情况下,我想做的是在 AJAX 替换的 DOM 节点上运行 destroyRecursive。我已经尝试了以下两种方法,但都不起作用(我相信 destroyRecursive 是用于小部件而不是 DOM?):

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

有没有一种好的方法可以做到这一点,还是我需要尝试确保我所有的 id 都是不同的?

【问题讨论】:

【参考方案1】:

你走在正确的轨道上,你是正确的,destroyRecursive 只存在于小部件上。但是,有几种选择可以完成您想做的事情。

如果您在很大程度上使用小部件,并且有问题的 div 经常被用作存储包括小部件在内的内容的存储桶,那么我强烈建议您查看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 文档中了解更多信息:

http://dojotoolkit.org/reference-guide/dijit/layout/ContentPane.html http://dojotoolkit.org/api/dijit/layout/ContentPane

或者,如果您不想使用小部件来保存您的内容,您可以在您的 div 中查找小部件并自行销毁它们。这是最简单的方法:

dojo.forEach(dijit.findWidgets(dojo.byId('main')), function(w) 
    w.destroyRecursive();
);

【讨论】:

AMD 注释:dojo.forEach - 导入 "dojo/_base/array" 作为数组,然后使用 array.forEach | dijit.findWidgets - 导入“dijit/registry”然后使用registry.findWidgets 如果您仅在 HTML 模板中定义了 contentPane,如 Leading pane 所以基本上在 javascript 中我需要销毁该窗格内的小部件。【参考方案2】:
dojo.query('selector').forEach(function(node)
   dijit.byNode(node).destroyRecursive(true);
);

基本上,选择节点...您可以使用dojo.byNode(node),然后destroyRecursive(true);获取映射为小部件对象

【讨论】:

【参考方案3】:

我解决了一个类似的问题,在重新加载之前使用 destroyRecursive(false) 删除内容后使用 dijit.registry.remove('idName') 从注册表中删除它。

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

【讨论】:

【参考方案4】:

如果您要在一个页面上销毁多个小部件,则以下解决方案适用于我。

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

  );

【讨论】:

以上是关于dojo:通过 dom 节点销毁所有小部件的主要内容,如果未能解决你的问题,请参考以下文章

Dojo 中有没有办法在 DOM 元素中查找所有小部件后代?

Dojo vs JQuery 编程小部件创建

小部件上的 dojo 查询

在Dijit销毁小部件

获取元素内的所有小部件

Dojo 和 Ajax - 渲染小部件