Javascript &引用;this.domNode为空";扩展对话框时

Javascript &引用;this.domNode为空";扩展对话框时,javascript,dojo,Javascript,Dojo,我正在尝试使用与dialog相同的templateString设置自定义对话框,但在内容区域中添加了custom require([ "dojo/_base/declare", "dojo/_base/lang", "dojo/dom-construct", "dijit/_WidgetsInTemplateMixin", "dijit/Dialog" ], function (declare, lang, domConstruct, _WidgetsIn

我正在尝试使用与dialog相同的templateString设置自定义对话框,但在内容区域中添加了
custom

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();
});
需要([
“dojo/_base/declare”,
“dojo/_base/lang”,
“dojo/dom构造”,
“dijit/_WidgetsInTemplateMixin”,
“dijit/Dialog”
],函数(declare,lang,domConstruct,_WidgetsInTemplateMixin,Dialog){
var CustomDialog=declare([Dialog,_WidgetsInTemplateMixin]{
模板字符串:
''+
''+
''+
''+
“x”+
''+
''+
' '+
“习俗”+
''+
'' ,
构造函数:函数(args,srcNodeRef){
lang.mixin(this,args);
},
});  
var div=domConstruct.toDom(“”);
domConstruct.place(div,document.body);
var widget=newcustomdialog({},div);
widget.startup();
widget.show();
});

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


删除
\u WidgetsInTemplateMixin
可使其正常工作。为什么模板小部件会导致此问题出现?

我编辑了我的回复,因为虽然我的原始回复是有效的,但正如Shoe所指出的,这并不是问题的原因。很抱歉

我更仔细地研究了这一点。发生的情况是,在对话框启动之前,内部的
ContentPane
实际上已经被销毁,然后当它确实尝试启动时,它会尝试启动已经销毁的
ContentPane
。但是,被销毁的小部件的
domNode
引用无效,并且
ContentPane
在其
启动
功能期间间接查看
domNode.parentNode
,从而导致错误

IIUC,小部件被过早销毁的原因首先是因为您的对话框在
buildRendering
期间解析模板中的小部件,然后在
\u applyAttributes
中的
buildRendering
之后立即解析,
对话框
内容
设置器最终会使用最初解析的内容调用,这最终会销毁最初解析的内容。实际上,在这里尝试使用
\u WidgetsInTemplateMixin
是双重解析。如果您在
containerNode
之外的某个地方呈现小部件(这是
ContentPane
专门解析的节点),您大概不会遇到这个问题

FWIW,当我需要在对话框中放置一个自定义小部件时,我不想摆弄整个对话框的模板,所以我采取相反的方法-我开发自定义小部件,然后简单地将对话框的
内容设置为该自定义小部件的一个实例。对于您来说,这可能是一种更直接的方法

以下是小部件作为内容方法的示例:

原始响应 在对话框实际位于文档流中之前,您正在调用
启动
,而其中一个子窗口小部件不希望这样。小部件的
startup
方法只能在小部件的DOM处于文档流中时调用,因为
startup
是创建生命周期中可以执行维度敏感逻辑的唯一API

在对话框的情况下,
startup
将在第一次调用
show
时自动调用(因为在此之前它不会在流中),所以您根本不需要自己调用它


另外,我不确定您目前是否只是在测试,但是如果您扩展模板以添加
ContentPane
,那就太过分了-
对话框开始时已经扩展了
ContentPane
,所以您基本上已经有了一个。

如果我注释掉
widget.startup()
错误仍然存在。为什么会这样?我的总体目标是在
containerNode
中有一些(非布局)小部件。ContentPane只是为了演示而已。哎呀。是的。看来我搞错了。我再次尝试并编辑了我的回复。谢谢你的回复。最初,我一直在设置内容,而不是构建模板。然而,我发现attachPoints和attachEvents根本没有连接。如果我将containerNode中需要的内容捆绑到另一个小部件中,然后将对话框的内容设置到该小部件,声明性附加点和事件是否会被正确解析并附加到我的小部件上?是,作为
content
传递的模板化小部件实例将像任何其他模板化小部件一样访问其附加点。这与直接设置混合内容不同,正如您所观察到的,混合内容根本不会关注附加点/事件。下面是一个将模板小部件设置为内容的示例:此外,您应该能够通过内容小部件中的
this.getParent()
访问该对话框。很高兴听到这个消息。谢谢你的帮助,肯。