【问题标题】:dojo dijit.Dialog destroy underlay errordojo dijit.Dialog 破坏底层错误
【发布时间】:2011-03-12 21:53:20
【问题描述】:

我有一个扩展 dijit.Dialog 的类,但只是为我的站点设置默认功能和按钮。单击对话框的取消按钮时,将运行以下代码:

    this.actionDialog.destroyRecursive();
    this.actionDialog.destroy();

nbthis.actionDialog = dijit.Dialog

有时(并非总是)会引发以下错误:

Uncaught TypeError: Cannot call method 'destroy' of undefined
DialogUnderlay.xd.js:8

这会导致以下对话框无法正确显示。我正在使用来自 Google API 的 1.5。我是否缺少底层代码的某些内容?

Ken 回答后抛出的错误:

exception in animation handler for: onEnd
TypeError: Cannot read property 'style' of null

都来自dojo.xd.js:14。但是代码仍然可以正常工作。

【问题讨论】:

    标签: javascript dojo dialog


    【解决方案1】:

    我仍然不完全确定问题出在哪里,除了出于某种原因dijit.DialogUnderlay 代码变得混乱之外。 FWIW,这在 Dojo 1.6 中不会发生。

    当我在寻找一些潜在的解决方案时,我似乎无意中发现避免这个问题可能就像在销毁对话框之前立即在对话框上调用 hide() 一样简单,例如:

    this.actionDialog.hide();
    this.actionDialog.destroyRecursive();
    

    或者,您可能有兴趣隐藏对话框,然后在隐藏动画完成后将其销毁。

    以下是在 Dojo 1.5 及更早版本(已测试 1.3+)上执行此操作的方法:

    dlg.connect(dlg._fadeOut, 'onEnd', function() {
        this.destroyRecursive();
    });
    dlg.hide();
    

    在 1.6 中,fadeOut 动画不再在实例上公开(当然,无论如何它在技术上更早是私有的),但onHide 现在在动画结束时触发(而在它开始时立即触发)。不幸的是,需要 setTimeout 来解决由于分支中的其他代码调用 onHide 而发生的错误,该错误假定实例上仍然存在某些东西,而在我们销毁它之后不会再存在(参见 #12436)。

    dlg.connect(dlg, 'onHide', function() {
        setTimeout(function() { dlg.destroyRecursive(); }, 0);
    });
    dlg.hide();
    

    在 JSFiddle 上查看它的实际操作:http://jsfiddle.net/3MNRu/1/(有关问题中的原始错误,请参阅 the initial version

    【讨论】:

    • 非常感谢,我的代码在运行时总是抛出错误(请参阅更新后的帖子),但它似乎仍然可以正常工作。
    • 嗯。如果您连接到 onEnd,会发生这种情况吗?奇怪的。在动画的onEnd 回调中肯定有对this.domNode.style 的引用,但是该代码应该在您连接到它的任何函数之前执行。我想您甚至可以在 1.5 方法上尝试 setTimeout 技巧,看看是否有帮助。出于好奇,这是在什么浏览器上运行的?
    • 我正在 Chrome 上进行测试。明天我将创建一个小提琴,看看我是否可以在更基本的级别上修复它并上传它。再次感谢
    • 问题是附加到 onCancel 函数的事件再次调用 hide()。
    【解决方案2】:

    dialog.hide() 方法返回一个Deferred,你的代码可以像这样更具可读性:

    var dialog = this.actionDialog;
    dialog.hide().then(function(){ dialog.destroyRecursive(); });
    

    小心不要这样做:

    this.actionDialog.hide().then(function(){ this.actionDialog.destroyRecursive(); });
    

    then的上下文中this还有另外一个意思!

    【讨论】:

      【解决方案3】:

      你只需要调用destroyRecursive()

      第二个destroy命令可能是导致错误的原因,而错误可能是导致其他对话框出现问题的原因。

      http://dojotoolkit.org/api/1.3/dijit/_Widget/destroyRecursive

      销毁递归

      销毁 此小部件 及其后代。这是所有小部件用户都应调用以彻底丢弃小部件的通用“析构函数”函数。一旦一个小部件被销毁,它就会从管理器对象中移除。

      【讨论】:

      • 很好的建议,但这不是导致问题的原因 - 我只用destroyRecursive 调用来模拟它。 jsfiddle.net/3MNRu(点击展示,点击销毁,点击展示,点击销毁,繁荣)
      • 嗯,值得一试。我真的很讨厌 Dojo 的这些类型的错误,它们很难追踪。这是一个很棒的框架,我喜欢使用它,但是当我拥有这些神秘的错误时,你需要以不同的方式做一件小事,这让我非常抓狂。不过,Ken 的解决方案看起来很有趣,也许可以。
      【解决方案4】:

      我收到 IE8 错误:'this.focusNode.form' is null or not an object。我发现这是 dialog.hide() 返回延迟的结果。我自己写了_closeDialog,它消除了IE错误。

      _closeDialog : function(cntxt){
              cntxt.popup.hide().then(
              function(){
                  cntxt.popup.destroyRecursive(false);
                  cntxt.popup.destroy(false);
                  cntxt.destroyRecursive(false);
                  cntxt.destroy(false);
              });
          },
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-02-19
        • 1970-01-01
        • 1970-01-01
        • 2018-12-14
        • 2013-08-05
        • 2017-08-18
        相关资源
        最近更新 更多