JQuery对话框:如何进行部分页面刷新并每次获得新对话框

JQuery对话框:如何进行部分页面刷新并每次获得新对话框,jquery,ajax,jquery-ui,dialog,partial-page-refresh,Jquery,Ajax,Jquery Ui,Dialog,Partial Page Refresh,在尝试创建对话框然后进行部分页面渲染时,我的JQuery对话框出现工作流问题。我将尝试介绍一个示例场景,并对冗长的问题描述提前表示歉意: 页面将加载html,我希望将其转换为JQuery对话框。对话框是在document.ready上创建的(使用.dialog()),但autoOpen属性设置为false。当JQuery创建对话框时(如果我使用Firebug检查页面),对话框html实际上从其正常位置剥离,并固定在文档的最末端,周围有一些包装类。用户通过单击仅执行$dialogDiv.dialo

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

页面将加载html,我希望将其转换为JQuery对话框。对话框是在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上只有一个真正的对话框)

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

非常感谢。

根据销毁对话框删除对话框功能并将其恢复到初始状态,但不会将其从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();
  });
}

在解决了这个问题和前面给出的答案后,我发现答案中缺少一些重要的细节。这里最重要的一点是,虽然
.dialog(“destroy”)
将div恢复到其初始状态,但它不会将div恢复到其在DOM中的原始位置。(BAHDev的问题首先提到UI对话框是如何移动div的。)这对于Ajax操作至关重要,并且应该在jQuery文档中澄清div位置的更改/不更改(这会节省我很多时间)

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

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

在测试(jQuery 1.4.4,UI 1.8.10)中,我发现原始div上的
.dialog(“destroy”)
与UI对话框父div上的
.remove()
的工作原理完全相同。也就是说,只有UI对话框包装器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对话框包装器和原始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中测试了一些。

@czarchic,感谢您的回复。你可能是唯一一个花时间看完整个问题的人。不过,还有一个问题。。我还有其他对话框窗口,如错误和警报对话框,我不想摆脱它们。使用您提供的方法,这些文件也会被清空和删除。查看JQuery创建的对话框,它为外部包装器提供了每个对话框上相同的类列表,即
ui对话框ui小部件ui小部件内容ui角落所有ui可拖动的
。如何指定要清空和删除哪些对话框,以及不清空和删除哪些对话框?再次感谢。
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,
    });