0

我一直在使用dojo 1.8 框架来创建一个包含其他一些菜单小部件的小部件。当我创建它的实例时,它会出现,但仅显示基本模板元素,并且在仔细检查下,尚未添加菜单小部件。然后,当我创建它的第二个实例(通过按钮单击)时,它会正确显示,包括菜单。

这真的让我很困惑,有什么想法吗?

哦,顺便说一下,我正在小部件实例上调用 startup()。

这是我的模板的代码...

<div class="${!baseClass}ConfigPanel">
        <div data-dojo-attach-point="heading">Configure data</div>
        <div id="menuContainer" data-dojo-attach-point="menu"></div>
</div>

这是我的小部件的代码...

define(
    ["dojo/_base/array",
    "dijit/Menu",
    "dijit/MenuItem",
    "dijit/PopupMenuItem",
    "dojo/_base/declare",
    "dijit/_WidgetBase",
    "dijit/_TemplatedMixin",
    "dojo/text!gdv/chart/configuration/panel/chartConfigTemplate.html",
    "dojo/domReady!"],
    function (ArrayUtil, Menu, MenuItem, PopupMenu, declare, WidgetBase, TemplatedMixin, template){

        var _menuData = [{title:"Region", data:["Region1", "Region2", "Region3"]},
                                        {title: "Variable", data:["variable1", "variable2", "variable3"]},
                                        {title: "Period", data:["period1", "period2"]},
                                        {title: ["latest", "rt1", "rt2"]}];


        /**
         * Build menu items up with a popup menu style
         */
        function buildMenu(nodeId, menuItems){
            var mainMenu = new Menu({label: "main menu"}, nodeId);
            var subMenuCollection = [];
            var subMenu;

            ArrayUtil.forEach(menuItems, function(item, index){
                subMenu = new Menu({label: item.title});
                subMenuCollection.push(subMenu);

                //loop through each item in data and create a new menu item from it
                ArrayUtil.forEach(item.data, function(subItem, subIndex){
                    subMenu.addChild(new MenuItem({label: subItem}));
                });

                //set the sub menu to popup from the main menu
                mainMenu.addChild(new PopupMenu({label: item.title, popup: subMenu}));

            });

            //create the menus
            mainMenu.startup();

            //start each sub menu
            ArrayUtil.forEach(subMenuCollection, function (item, index){
                item.startup();
            });
        }

        //return a new widget class
        return declare([WidgetBase, TemplatedMixin], {
            templateString: template,
            baseClass: "plumePlots",

            //when dom structure is ready but before page insertion
            postCreate: function(){

                //run all parent postCreate functions
                this.inherited(arguments);

                var menuNode = this.menu;
                buildMenu(menuNode.id, _menuData);
            }
        });
    }
)
4

1 回答 1

1

好的,我找到了答案,这取决于小部件的生命周期,直接来自 dojo小部件教程的引用应该有助于解释......

启动()

可能 Dijit 生命周期中第二重要的方法是启动方法。此方法旨在处理任何 DOM 片段实际添加到文档后的处理;在创建并启动任何潜在的子小部件之前,它不会被触发。这对于复合小部件和布局小部件很有用。

所以事实证明我试图引用一个尚未添加到文档中的 dom 元素。

为了修复我的代码,我只是将创建菜单小部件的代码从 postCreate() 方法移到了 startup() 方法中,问题解决了,这里是显示更改的代码片段......

//return a new widget class
        return declare([WidgetBase, TemplatedMixin], {
            templateString: template,
            baseClass: "plumePlots",

            //when dom structure is ready but before page insertion
            postCreate: function(){             
                //run all parent postCreate functions
                this.inherited(arguments);
            },

            startup: function(){  // added startup function
                var menuNode = this.menu; // code moved to here
                buildMenu(menuNode.id, _menuData); // and here
            }
        });
于 2012-11-22T14:15:48.957 回答