2010-01-19 39 views
9

當我嘗試創建對話框並進行部分頁面渲染時,我的工作流問題與我的JQuery對話框有關。我會嘗試通過一個示例場景,並提前對長問題描述表示歉意:JQuery對話框:如何進行局部頁面刷新並每次獲取新對話框

頁面加載時,我希望將其轉換爲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上只有一個真正的對話框)。

我在想,我可能需要在某個時候銷燬對話框或某些東西,但是我沒有使用這種方法。有沒有人有任何想法?

非常感謝。

回答

7

根據the docs銷燬對話框會刪除對話框功能,並將其恢復爲初始狀態,但不會將其從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(); 
    }); 
} 
+0

@czarchaic,謝謝你的迴應。你可能是唯一花時間閱讀整個問題的人。後續問題,雖然..我有其他對話窗口,如錯誤和警報對話框,我不想擺脫。使用您提供的方法,這些將被清空並刪除。看看JQuery製作的對話框,它爲每個外層包裝提供了相同的類別列表,即「ui-dialog ui-widget ui-widget-content ui-corner-all ui-draggable」。我怎樣才能指定哪些對話框清空和刪除,哪些不是?再次感謝。 – BAHDev 2010-01-19 20:44:51

+0

@BAHDev。我會更新我的帖子。 – czarchaic 2010-01-20 14:02:46

0

通過這個問題,並給出答案之前的工作後,我發現從答案缺少一些重要的細節。這裏最重要的一點是,儘管.dialog("destroy")確實將div恢復到其預初始狀態,但它不會將div恢復到其在DOM中的原始位置。 (BAHDev的問題提到了UI Dialog如何移動div。)這對Ajax操作至關重要,這個div位置的改變/不改變應該在jQuery文檔中加以說明(這會爲我節省很多時間)。

如果Ajaxing只是對話框div的內容,那麼這種行爲可能並不重要,因爲無論DOM駐留在哪裏,都可以輕鬆查找和重寫div內容。但是,如果您的對話內容與其他對象內嵌Ajax,則將原始位置移動div可能會導致稍後的Ajaxing在原始位置創建另一個div,從而導致具有相同ID的多個div。

例如,我要求在一次Ajax調用中列出產品和一長串產品列表。短名單進入屏幕,長列表進入隱藏對話框。因爲列表是相關的,所以在一次Ajax調用中抓住它們是有意義的。由於UI對話框將長列表從容器中移出,並將其粘貼到HTML主體的末尾,當我請求一個新列表時,我最終得到兩個ID相同的div,每個div包含一個不同的長列表 - 一個在Ajax容器中,另一個在主體的末尾。我看到要處理這個問題的最正確方法是首先在Ajaxing一個新的長列表之前徹底摧毀舊的長列表。 (也可以檢查UI對話框對象,並在代碼中移動長列表,但這很麻煩,也可能會丟失div屬性。)

在測試中(jQuery 1.4.4,UI 1.8.10),我發現.dialog("destroy")原始div的作品與UI Dialog父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"); 

因此,最好的辦法都滅了用戶界面對話框包裝和原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。

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, 
    });