文档中的 Dojo 示例因“id is already registered”错误而失败

Posted

技术标签:

【中文标题】文档中的 Dojo 示例因“id is already registered”错误而失败【英文标题】:Dojo example in documentation fails with "id is already registered" error 【发布时间】:2014-07-20 16:33:39 【问题描述】:

我无法让 dojo 的官方文档中列出的 dojo 示例正常工作。 当我从他们的网页运行 Dojo 的演示时,它运行良好。但是,当我复制并粘贴代码(如下所示)并尝试在任何网络浏览器中运行它时,我得到了一个错误。对于多个不同的网络浏览器,我在控制台日志中收到一条错误消息:

错误:尝试使用 id==borderContainerThree 注册小部件,但 id已经注册了

这令人沮丧,因为我无法弄清楚导致我的代码失败的区别,但他们的代码可以工作。 我已经从网页上逐字复制了他们的代码。

页面上给出了示例: http://dojotoolkit.org/reference-guide/1.9/dijit/layout/BorderContainer.html 并且标题为: “Dijit 模板中的 BorderContainer”

此处 (dojo 1.8: Error: Tried to register widget with id==main_bContainer but that id is already registered) 和此处 (Dojo - "Tried to register widget with id==centerPane but that id is already registered") 的类似问题说这可能是因为我调用了 parser.parse 两次,但如果我取消注释 parser.parse 行, 错误消失,但网页上没有显示内容。

我的代码如下:

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

    <title>dijit/layout/BorderContainer &mdash; The Dojo Toolkit - Reference Guide</title>

    <link rel="stylesheet" href="http://dojotoolkit.org/reference-guide/1.9/_static/default.css" type="text/css" />
    <link rel="stylesheet" href="http://dojotoolkit.org/reference-guide/1.9/_static/pygments.css" type="text/css" />
    <link rel="stylesheet" href="http://dojotoolkit.org/reference-guide/1.9/_static/css/site.css">
    <link rel="stylesheet" href="http://dojotoolkit.org/reference-guide/1.9/_static/js/docs/resources/guide.css">
    <script type="text/javascript">
        dojoConfig = 
            async: true
        ;
    </script>
    <script type="text/javascript" src="http://dojotoolkit.org/reference-guide/1.9/_static/js/dojo/dojo.js"></script>
    <script type="text/javascript" src="http://dojotoolkit.org/reference-guide/1.9/_static/js/docs/guide.js"></script>

</head>
<body class="claro" >
My Test


<script type="text/javascript">
    require([
        "dojo/parser",
        "dojo/_base/declare",
        "dijit/_WidgetBase",
        "dijit/_TemplatedMixin",
        "dijit/_WidgetsInTemplateMixin",
        "dijit/form/Button",
        "dijit/layout/ContentPane",
        "dijit/layout/BorderContainer",
        "dijit/layout/TabContainer",
        "dijit/layout/AccordionContainer",
        "dijit/layout/AccordionPane"
    ], function(parser, declare, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin)
        declare("MyDijit",
                [_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], 
                    // Note: string would come from dojo/text! plugin in a 'proper' dijit
                    templateString: '<div style="width: 100%; height: 100%;">' +
                            '<div data-dojo-type="dijit/layout/BorderContainer" design="headline" ' +
                            '  style="width: 100%; height: 100%;" data-dojo-attach-point="outerBC">' +
                            '<div data-dojo-type="dijit/layout/ContentPane" region="center">MyDijit - Center content goes here.</div>' +
                            '<div data-dojo-type="dijit/layout/ContentPane" region="bottom">MyDijit - Bottom : ' +
                            ' <div data-dojo-type="dijit/form/Button">A Button</div>' +
                            '</div>' +
                            '</div></div>'
                );

        parser.parse();
    );
</script>

<div data-dojo-type="dijit/layout/BorderContainer" data-dojo-props="gutters:true" id="borderContainerThree">
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'top'">
        <div data-dojo-type="dijit/form/Button" id="createButton">Create Inner Dijit
            <script type="dojo/on" data-dojo-event="click">
                require(["dojo/dom", "dojo/dom-construct"], function(dom, domConstruct)
                    // Create a new instance
                    var newdijit = new MyDijit(, domConstruct.create('div'));
                    newdijit.placeAt(dom.byId('mydijitDestination'));
                    newdijit.startup();
                );
            </script>
        </div>
    </div>
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'left', splitter:false">
        OUTER LEFT<br />
        This is my content.<br />
        There is much like it,<br />
        but this is mine.<br />
        My content is my best friend.<br />
        It is my life.<br />
        I must master it,<br />
        as I must master my life.
    </div>
    <div data-dojo-type="dijit/layout/ContentPane" data-dojo-props="region:'center', splitter:false">
        <div id="mydijitDestination" style="width: 100%; height: 100%"></div>
    </div>
</div>


</body>
</html>

任何关于我做错了什么的建议将不胜感激。

【问题讨论】:

【参考方案1】:

该错误确实表明您尝试两次创建具有相同 ID 的小部件,因为您有两个具有相同 ID 的元素,或者因为您要解析相同的标记两次。

我建议评论parser.parse() 行并将parseOnLoad: true 添加到dojoConfig,例如:

<script type="text/javascript">
    dojoConfig = 
        async: true,
        parseOnLoad: true
    ;
</script>

注释解析行时看不到任何内容的原因是另一个问题。 Dojo 中的大多数布局小部件都是根据父 DOM 节点的空间生成它们的布局。这意味着您必须首先使用 CSS 设置小部件的空间,例如:

#borderContainerThree 
    width: 100%;
    height: 100%;


html, body 
    width: 100%;
    height: 100%;
    margin: 0;
    overflow:hidden;

如果你这样做,那么一切都应该正常,就像在这个小提琴中一样:http://jsfiddle.net/92NT4/

【讨论】:

Dimitri,添加样式表有效。谢谢!正如您所建议的,我还注释掉了 parser.parse 以停止错误消息,并将 parseOnLoad 设置为 true。我还必须注释掉可能也导致错误的 Dojo 脚本“dojotoolkit.org/reference-guide/1.9/_static/js/docs/guide.js”。非常感谢您的帮助,小提琴页面帮了大忙。

以上是关于文档中的 Dojo 示例因“id is already registered”错误而失败的主要内容,如果未能解决你的问题,请参考以下文章

Zend 2 + Dojo 文档…

require的路径问题(比较重要)

Dojo1.11官方教程文档翻译(1.3)新的Dojo

DOJO按钮示例[关闭]

dojo源码阅读之dojo/Stateful

dojo源码阅读之dojo/Stateful