dojo: 小部件已注册错误
Posted
技术标签:
【中文标题】dojo: 小部件已注册错误【英文标题】:dojo: widget already registered error 【发布时间】:2015-05-14 15:24:52 【问题描述】:我知道这似乎是一个常见错误,我已经尝试实现一些 jquery 或 Dojo 代码来解决问题,但到目前为止没有任何帮助 - 我不断收到相同的错误:小部件已注册 ID...
这是我的代码:
$( "div" ).remove( "#div_temperature_legend" ); //jquery
dojo.create("div", id: "div_temperature_legend", innerhtml: "<p></p>" , "legendPanel");
var legend = new esri.dijit.Legend(
map: map,
layerInfos: [ layer: layer, title: "Temperature" ],
, "div_temperature_legend");
legend.startup();
上面的代码在一个按钮点击函数中,这个函数本身就是一个大的道场require()
函数的一部分;并第一次工作。 jQuery 行似乎确实被删除了,因为图例不会在新创建的 div_temperature_legend
层中重复。
无论如何,我已经尝试过 dojo 的 destroy()
函数,但我仍然得到同样的错误。我想不知何故,我需要在某个地方 register
这个 div 然后销毁它。但是怎么做?在哪里?在我的代码上下文中?
理想情况下,代码应该检测小部件是否存在并且不会创建另一个图例。
谢谢。
【问题讨论】:
jquery 代码删除了div
,但小部件的引用(即 esri.dijit.Legent 在注册表中仍然可用。要销毁小部件,这会删除注册表中的引用需要做这样的事情。legend.destroy()
在创建 new esri.dijit.Legend
之前。
【参考方案1】:
错误在于dojo 小部件的错误处理。一旦创建,它将通过其 ID 在注册表散列中设置。你也可以 a) 处理小部件 dojo 方式 或者 b) 每次为小部件创建唯一 ID。
如果您有多个相同类型的小部件,则使用 ID 不是一个好主意。最好跳过 ID 并使用 class 属性。 ID 将被自动分配,但您对此不感兴趣,因为选择器可以使用您分配的类名。
【讨论】:
好的,那么如何使用类属性呢?除非我以某种方式将其删除,否则小部件不会继续获取图例内容吗?就像我现在正在使用 jquery 一样?谢谢 $('.myWidgetType').forEach( function(el) dijit.byNode(el).destroy(); //1.销毁小部件的所有实例 $('.esriLegend').forEach( function(el) dijit.byNode(el).destroy(); // 2. 以与您相同的方式创建一个新实例,但使用 className 代替id.var node = dojo.create("div", class: "esriLegend", innerHTML: "" , "legendPanel"); new esri.dijit.Legend(... ,node).startup(); 模板化的小部件使用起来稍微简单一些。【参考方案2】:这是我基于 @Sasha 的唯一 Div ID 理念实现我的解决方案的方式:
$("#"+div_legend_global).remove();
div_legend_global = "div_" + new Date().getTime().toString();//div_legend_global defined globally
dojo.create("div", id: div_legend_global, innerHTML: "<p></p>" , "legendPanel");
var legend = new esri.dijit.Legend(
map: map,
layerInfos: [ layer: layer, title: "Temperature" ],
, div_legend_global);
legend.startup();
所以我定义了一个名为div_legend_global
的全局变量,然后在按钮单击函数中为其分配唯一值。然后,该唯一值将成为 create Legend() 函数的 ID。在后续调用之后,jquery 会移除唯一的 div,从而防止显示多个图例实例。
现在,Dojo 可能会将 div 保留在其堆栈中,我认为从堆栈中删除会更好。但我现在还好。
谢谢@Sasha。
【讨论】:
我认为这会在您的代码中造成内存泄漏。即使 domNode 被销毁,dojo 对象仍然驻留在内存中。另一种方法是使用dijit.registry( 'widget_id').destroy()
,然后重新创建图例小部件。
好的,但是我在哪里以及如何将 div 添加到注册表中——我想我曾怀疑我需要做类似的事情,但无法弄清楚。我确实尝试过 domConsrtruct.destroy() 但没有帮助。谢谢
Meengla 如果您正在创建它,则无需注册小部件。它应该已经注册了。如果您绝对需要 ID,您可以考虑另一种选择,即每次使用注册表的 getUniqueId 函数为您提供一个唯一 ID,您可以将其存储在您选择的某个变量中。有关 getUniqueId 和所有其他注册表方法的更多信息,请参阅 dojotoolkit.org/api/#1_10dijit_registry_getUniqueId。
frank 的评论也应该是一个答案。 ;) 这是mixing up DOM and Dijit APIs 的经典案例(该博文已经过时,但其中的破坏部分在 5 年后仍然适用)。 DOM 销毁 API 对 Dijit 小部件一无所知。
对不起,但没有一个建议奏效:我试过 Frank 的但仍然得到同样的错误——显然破坏不起作用。我可以通过使用 'var node_legend = dom.byId("div_legend")' 进行检测,然后尝试使用 Frank 和 'domConstruct.destroy("div_legend");'但没有效果——同样的错误。我继续前进。这个留到以后再说。谢谢大家。以上是关于dojo: 小部件已注册错误的主要内容,如果未能解决你的问题,请参考以下文章
dijit.registry.filter / dijit.registry.map 不会迭代,尽管 dijit.registry 充满了已注册的小部件?