扩展Dialog时“this.domNode为null”

时间:2014-08-15 21:42:40

标签: javascript dojo

我正在尝试使用与Dialog相同的templateString设置自定义对话框,但在内容区域添加<div><div data-dojo-type="dijit/layout/ContentPane">Custom</div></div>

require([
    "dojo/_base/declare",
    "dojo/_base/lang",
    "dojo/dom-construct",
    "dijit/_WidgetsInTemplateMixin",
    "dijit/Dialog"
], function (declare, lang, domConstruct, _WidgetsInTemplateMixin, Dialog) {
    var CustomDialog = declare([Dialog, _WidgetsInTemplateMixin], {
        templateString: 
            '<div class="dijitDialog" role="dialog" aria-labelledby="${id}_title">'+
                '<div data-dojo-attach-point="titleBar" class="dijitDialogTitleBar">'+
                    '<span data-dojo-attach-point="titleNode" class="dijitDialogTitle" id="${id}_title"'+
                              'role="heading" level="1"></span>'+
                    '<span data-dojo-attach-point="closeButtonNode" class="dijitDialogCloseIcon" data-dojo-attach-event="ondijitclick: onCancel"'+
                        'title="${buttonCancel}" role="button" tabindex="0">'+
                        '<span data-dojo-attach-point="closeText" class="closeText"'+ 'title="${buttonCancel}">x</span>'+
                    '</span>'+
                '</div>'+
               ' <div data-dojo-attach-point="containerNode" class="dijitDialogPaneContent">'+
                    '<div><div data-dojo-type="dijit/layout/ContentPane">Custom</div></div>'+
                '</div>'+
            '</div>' ,
        constructor: function (args, srcNodeRef) {
            lang.mixin(this, args);
        },
    });  

    var div = domConstruct.toDom("<div id='saveMapWidget'></div>");
    domConstruct.place(div, document.body);    
    var widget = new CustomDialog({}, div);
    widget.startup();
    widget.show();
});

Here's the JSFiddle

运行此代码会给我TypeError: this.domNode is null

删除_WidgetsInTemplateMixin会使其正常工作。为什么模板小部件会导致此错误?

1 个答案:

答案 0 :(得分:1)

我已经编辑了我的回复,因为虽然我的原始回复是有效的,但并不是导致问题的原因,正如Shoe指出的那样。对不起。

我已经更仔细地追查了这一点。发生的事情是你的内部ContentPane实际上在对话框启动之前被销毁,然后当 尝试启动时,它会尝试启动已经 - 摧毁了ContentPane。但是,已销毁的小部件的domNode引用无效,ContentPane在其domNode.parentNode函数期间间接查看startup,这会导致错误。

IIUC,小部件首先被过早销毁的原因是因为你的对话框在buildRendering期间在模板中解析小部件,然后在buildRendering _applyAttributes之后立即解析小部件content的{​​{1}} setter最终使用最初解析的内容进行调用,最终会破坏最初解析的内容。实际上,您可以尝试在此使用Dialog进行双重解析。如果你在_WidgetsInTemplateMixin之外的某个地方(这是containerNode专门解析的节点)呈现小部件,大概你不会遇到这个问题。

FWIW,当我需要在对话框中放置自定义小部件时,我不想摆弄整个对话框的模板,所以我采取相反的方法 - 我开发自定义小部件,然后只需将对话框的ContentPane设置为该自定义窗口小部件的实例。这可能是一种更直接的尝试方法。

以下是小部件内容方法的示例:http://jsfiddle.net/ddLp24wg/

原始回复

在对话框实际位于文档流程中之前,您正在调用content,而其中一个子窗口小部件并不期望这样。只有在窗口小部件的DOM位于文档流中时才应调用窗口小部件的startup方法,因为startup是创建生命周期中的一个API,其中维度敏感逻辑可以是进行。

对于Dialogs,startup将在第一次调用startup时自动调用(因为在此之前它不会被预期在流中),所以你不应该&# 39;根本不需要自己打电话。

此外,我不确定您是否仅进行了测试,但如果您正在扩展模板以添加show,那就太过分了 - { {1}}已经开始ContentPane,因此您基本上已经有了{。}}。