没有 id 的小部件上出现“id 已注册”错误

Posted

技术标签:

【中文标题】没有 id 的小部件上出现“id 已注册”错误【英文标题】:"id is already registered" error on widget with no id 【发布时间】:2014-11-21 22:01:05 【问题描述】:

我是 dojo 和 dijit 的新手,在创建包含其他小部件的小部件时遇到了大约一周的麻烦。我查看了许多关于此错误的其他文章,但没有任何运气来实施其中列出的解决方案。

简而言之,我使用的是 dojo 1.10,并且我有一个包含非模板小部件的模板小部件。当我加载我的页面时,我收到错误 Error: Tried to register widget with id==mtt_SearchPane2_0_searchPane but that id is already registered。

我没有给出任何明确的 id,也没有在任何地方调用 parse,所以我有点难过。

这是我的html

<body class="claro">
    <div id = "appLayout" ></div>

    <script src="js/dojo/dojo.js" data-dojo-config="async:true, parseOnLoad:true"></script>
    <script>
        require([
            "dijit/registry", 
            "dijit/layout/BorderContainer",
            "mtt/SearchPane2",
            "dojo/domReady!"],
            function(registry, BorderContainer, SearchPane )
            
                var appLayout = new BorderContainer(
                    design: "headline"
                , "appLayout");

                var searchPane = new SearchPane (  region : "center"  );
                appLayout.addChild ( searchPane );
                searchPane.startup ();

                appLayout.startup();                    

            );
    </script>
</body>

我有一个 SearchPane 小部件,如下所示:

define  ( 
[
    "dojo/_base/declare", 
    "dijit/_WidgetBase",
    "dijit/_TemplatedMixIn",
    "dijit/_WidgetsInTemplateMixin",
    "dojo/text!mtt/templates/SearchPane2.html",
    "mtt/ImageCheckBox",
    "dojo/domReady!"
], 
function ( declare, _WidgetBase, _TemplatedMixIn, _WidgetsInTemplateMixIn, template, ImageCheckBox )

    return declare ( 
        "mtt.SearchPane2",
        [ _WidgetBase, _TemplatedMixIn, _WidgetsInTemplateMixIn ], 
        
            templateString: template,
         
    );
);

使用关联的模板:

<div>
    <div
        data-dojo-attach-point="checkBox"
        data-dojo-type="mtt/ImageCheckBox"
    />
    <div data-dojo-attach-point="contentPane"></div>
    moo
</div>

而这又包含一个 ImageCheckBox:

require([
    "dojo/_base/declare", 
    "dijit/_WidgetBase"
], function(declare, _WidgetBase )


    return declare("mtt/ImageCheckBox", [_WidgetBase ], 
    );
);

.. 没有模板。

奇怪的是,如果我的 ImageCheckBox 继承自 _TemplatedMixin 而不是 _WidgetBase,那很好。

提前感谢任何可以阐明这一点的人。

【问题讨论】:

【参考方案1】:

我注意到这里有几个问题。首先,您在ImageCheckBox 中使用require()。显然,您需要执行与 SearchPane2 小部件中相同的操作,您将需要使用 define()


SearchPane2 中,您正在使用模块"dijit/_TemplatedMixIn",该模块不存在,因为“mixin”中的第二个“i”也应该是小写的。正确的模块名称是"dijit/_TemplatedMixin"


但是你得到这些“widgets already registered”错误的原因是你没有覆盖ImageCheckBox中的DOM。这里发生的事情很有趣:

您在SearchPane2 的模板内使用data-dojo-type="mtt/ImageCheckBox" mixin _WidgetsInTemplateMixin 确保 mtt/ImageCheckBox 模块已加载 但是,您的 _mtt/ImageCheckBox 不会更改 DOM,因此原始 DOM 节点(上面带有 data-dojo-type="mtt/ImageCheckBox")将保留 然后,在您的模块加载后,parseOnLoad: true 属性将呈现所有以声明方式实例化的小部件 因为data-dojo-type="mtt/ImageCheckBox" 仍在您的模板上,它会尝试重新注册小部件,这会导致您收到错误。

当您从dijit/_TemplatedMixin 继承或实际实现您的小部件时显然不会发生这种情况,因为那时您可能会覆盖当前的DOM 节点,因此data-dojo-type attr 消失。

或者您可以在ImageCheckBox 中执行以下操作:

define([
  "dojo/_base/declare", 
  "dijit/_WidgetBase",
  "dojo/dom-attr"
], function(declare, _WidgetBase, domAttr) 
    return declare("mtt/ImageCheckBox", [_WidgetBase], 

      postCreate: function() 
        domAttr.remove(this.domNode, "data-dojo-type");
      
    );
);

可以在Plunker 上找到一个工作示例。

【讨论】:

非常感谢您的详细回复。我已经实现了您的建议并为 CheckBox 小部件完成了一些基本实现,现在一切看起来都在工作。将此标记为已回答。

以上是关于没有 id 的小部件上出现“id 已注册”错误的主要内容,如果未能解决你的问题,请参考以下文章

错误:尝试使用 id==grid1 注册小部件,但该 id 已注册

私人JavaScript小部件

Qt4:从 QDockedWidget 的子类访问 QtDesigner 创建的小部件

小部件未出现在小部件列表中

我在列中有几个扩展的小部件。首先我展开一个小部件。当我展开第二个时,第一个应该自动折叠

Android Studio v 3.1.4 中的小部件不会出现在设计模式中