9

在尝试创建对话框然后进行部分页面渲染时,我的 JQuery 对话框出现工作流问题。我将尝试通过一个示例场景,并为冗长的问题描述提前道歉:

页面加载,带有我想变成 JQuery 对话框的 html。对话框是在 document.ready 上创建的(使用.dialog()),但 autoOpen 属性设置为 false。当 JQuery 创建对话框时(如果我使用 Firebug 来检查页面),对话框 html 实际上已从其正常位置剥离并停留在文档的最后,周围有一些包装类。用户通过单击仅执行$dialogDiv.dialog('open').

这样一切正常。问题是有时我使用 AJAX(使用 ASP.NET MVC RenderPartial)进行部分页面重新加载。我正在刷新的页面部分恰好包含所有对话框 html,因此会被重新写出。但请记住对话框(包含所有 JQuery 包装类等)已经在文档的底部。那个 html 不是页面刷新的一部分,所以现在我被两组对话 html 困住了。这给了我各种各样的问题,因为我在页面上有重复的 id,并且这些 html 元素上的 jQuery 行为变得不可预测。当我开始进行 3、4、5 次部分页面刷新时,情况更糟,因为那时我有 3、4、5 组对话框 html(在 document.ready 上只创建了一个真正的对话框)。

我在想我可能需要在某个时候销毁对话框或其他东西,但我对这种方法没有任何运气。有没有人有任何想法?

非常感谢。

4

3 回答 3

7

根据文档,销毁对话框会删除对话框功能并将其恢复到初始状态,但不会将其从 DOM 中删除。

由于您要替换内容和对话框,因此您可以删除旧的。

$.ajax({
  url: '/some/url/',
  success:function(data){
    $('.ui-dialog').empty().remove();
    //add the new html and make the dialogs
  }
});

回应你的评论

我还没有看到你的代码,所以我不确定你是如何设置对话框的,但在一般意义上,我会用将被替换的对话框填充一个变量。

//inside document.ready
  var myDialog=$('#myDialog').dialog(),
  myOtherDialog=$('#myOtherDialog').dialog(),
  permanentDialog=$('#permanentDialog').dialog(),
  destroyableDialogs=[myDialog, myOtherDialog];

//ajax callback
success: function(data){
  $.each(destroyableDialogs, function(i,n){
    n.empty().remove();
  });
}
于 2010-01-19T18:20:13.267 回答
0
Firs check the dialog is already exist then destroy that one and re-initilaze dialog on rendering
if ($("#dialogId").hasClass('ui-dialog-content')) {
      $('dialogId').dialog('destroy');
    }

    $("#dialogId").dialog({
      title: 'Warning',
      autoOpen: false,
      modal: true,
      width: 600,
      closeOnEscape: true,
      draggable: false,
      resizable: false,
    });
于 2015-02-16T07:35:01.233 回答
0

在解决了这个问题和给出的先前答案之后,我发现答案中缺少一些重要的细节。这里最重要的一点是,虽然.dialog("destroy")确实将 div 恢复到其预初始化状态,但它不会将 div 恢复到其在 DOM 中的原始位置。(BAHDev 的问题首先提到了 UI Dialog 如何移动 div。)这对 Ajax 操作至关重要,应该在 jQuery 文档中阐明 div 位置的更改/非更改(这可以为我节省很多时间)。

如果仅对对话框 div 的内容进行 Ajaxing,那么这种行为可能并不重要,因为您可以轻松地找到并重写 div 内容,无论它位于 DOM 中的哪个位置。但是,如果您的对话框内容与其他对象内联,则将 div 从其原始位置移动可能会导致稍后的 Ajaxing 在原始位置创建另一个 div,从而导致多个具有相同 ID 的 div。

例如,我在一次 Ajax 调用中请求了一个简短的产品列表和一个长的产品列表。短列表进入屏幕,长列表进入隐藏对话框。因为列表是相关的,所以在一次 Ajax 调用中同时获取它们是有意义的。因为 UI Dialog 将长列表移出它被 Ajaxed 放入的容器并将其卡在 HTML 正文的末尾,所以当我请求一个新列表时,我最终得到了两个具有相同 ID 的 div,每个 div 都包含一个不同的长列表-- 一个在 Ajax 容器中,一个在正文的末尾。我认为处理此问题的最正确方法是在 Ajaxing 新列表之前首先完全销毁旧的长列表。(也可以检查 UI Dialog 对象并在代码中移动长列表,但这很麻烦并且还可能丢失 div 属性。)

在测试(jQuery 1.4.4,UI 1.8.10)中,我发现在原始 div 上的工作方式与在 UI Dialog 父 div 上.dialog("destroy")完全相同。.remove()也就是说,只有 UI Dialog 包装器 div 被剥离,而原始 div 则保留其原始状态。换句话说,以下每一个都做同样的事情[注意:.empty() 没有明显的效果]:

// Three different ways to destroy just the UI Dialog
// (and leave the original div).
$(".ui-dialog:has(#myDialog)").remove();
$("#myDialog").parents(".ui-dialog").remove();
$("#myDialog").dialog("destroy");

因此,销毁 UI Dialog 包装器和原始 div 的最佳方法似乎是:

// Remove the old dialog and div to make way for a new one via Ajax.
$("#myDialog").dialog("destroy");
$("#myDialog").remove();

如果你想确保销毁所有副本——以防你不小心创建了太多调用太多的副本——.dialog()你需要在 #id 选择器前面添加一些东西,例如:

// Remove all old dialogs and divs to make way for a new one via Ajax.
$("div#myDialog").dialog("destroy");
$("div#myDialog").remove();

您可以在一行中执行此操作,但您的意图不太明显:

// Remove all old dialogs and divs to make way for a new one via Ajax.
// This technique is not recommended.
$("div#myDialog").parents(".ui-dialog").andSelf().remove();

我在 FF 中测试了所有这些,在 IE8 中测试了其中的一些。

于 2011-09-22T20:44:22.660 回答