【问题标题】:calling jQuery .remove() on custom UI widget causes infinite loop在自定义 UI 小部件上调用 jQuery .remove() 会导致无限循环
【发布时间】:2012-03-26 18:39:01
【问题描述】:

我创建了名为 uiPopover 的自定义 jQuery UI 小部件,与 UI-dialog 非常相似(事实上,大部分代码都是从它复制粘贴的)。这个小部件有一个自定义的销毁方法,它隐藏小部件并将其从 DOM 中删除。同样,它几乎是从 UI 对话框复制粘贴。

    destroy: function() {
        var self = this;

        if (self.overlay) {
            self.overlay.destroy();
        }
        self.close();
        self.element
            .removeData('popover');
        self.uiPopover.remove();
        console.log('afterRemove')

        return self;
    },

奇怪的是,这会导致无限循环并引发一些错误:

$('#element').popover();
$('#element').remove();

据我所知,问题是当我调用 .remove() 时,它会自动在我的小部件上调用 destroy()(这是 jQuery UI 中内置的),并且 destroy 方法尝试调用 remove( ) 再次在我的元素上,然后尝试再次调用 destroy() 等等..

但是,奇怪的是 UI 对话框不会发生这种情况。所以当我这样做时:

$('#element').dialog();
$('#element').remove();

一切正常...我的插件一定有问题,但我不知道是什么问题。

这里是我的插件的完整源代码:https://gist.github.com/2208569

【问题讨论】:

    标签: jquery-ui infinite-loop


    【解决方案1】:

    除了修改 jQuery UI 本身之外,您对destroy() 的递归调用无能为力。但是,您可以通过阻止 remove() 再次被调用来打破链条:

    destroy: function() {
        var self = this;
    
        if (self.overlay) {
            self.overlay.destroy();
        }
        self.close();
    
        if (self.element.data("popover")) {
            self.element.removeData("popover");
            self.uiPopover.remove();
        }
    
        return self;
    }
    

    请注意,您不必复制和粘贴代码来扩充现有小部件,就像小部件框架 supports prototype inheritance。如果您的小部件从$.ui.dialog 派生而不是复制其代码库,那么知道您的问题是否仍然存在将会很有趣。

    【讨论】:

    • 谢谢!这似乎可以解决问题。找出为什么它与$.ui.dialog 的行为方式不同会很有趣。也许当我有更多时间玩它时......
    猜你喜欢
    • 2011-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多