Диалог JQuery: как сделать частичное обновление страницы и каждый раз получать новые диалоги - PullRequest
9 голосов
/ 19 января 2010

У меня проблема с рабочим процессом с моими диалоговыми окнами JQuery, когда я пытаюсь создать диалоговые окна, а затем выполняю частичный рендеринг страницы. Я постараюсь пройти пример сценария и заранее извиняюсь за длинное описание проблемы:

Страница загружается с HTML, который я хотел бы превратить в диалоги JQuery. Диалоги создаются в document.ready (используя .dialog()), но свойство autoOpen имеет значение false. Когда JQuery создает диалоги (если я использую Firebug для проверки страницы), диалог html фактически удаляется из своего обычного местоположения и застревает в самом конце документа, с некоторыми классами-оболочками вокруг него. Пользователь открывает диалоги, щелкая ссылку, которая просто делает $dialogDiv.dialog('open').

Так что все работает нормально. Проблема в том, что бывают случаи, когда я делаю частичную перезагрузку страницы, используя AJAX (используя ASP.NET MVC RenderPartial). Часть страницы, которую я обновляю, содержит все диалоговые окна html, поэтому они переписываются. Но помните, что диалог (со всеми классами-оболочками JQuery и т. Д.) Уже находится в нижней части документа. Этот HTML не был частью обновления страницы, так что теперь я застрял с двумя наборами диалоговых HTML. Это вызывает у меня всевозможные проблемы, потому что у меня есть дубликаты идентификаторов на странице, и поведение jQuery для этих HTML-элементов становится непредсказуемым. Еще хуже, когда я начинаю делать 3, 4, 5 частичных обновлений страницы, потому что тогда у меня есть 3, 4, 5 наборов html диалогов (только один настоящий диалог был сделан в document.ready).

Я думаю, что в какой-то момент мне может понадобиться уничтожить диалоги или что-то в этом роде, но мне не повезло с этим подходом. У кого-нибудь есть идеи?

Большое спасибо.

Ответы [ 3 ]

7 голосов
/ 19 января 2010

Согласно документы , уничтожающие диалоговое окно, удаляют функциональность диалогового окна и возвращают его в состояние перед инициализацией, но не удаляют его из 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 голосов
/ 16 февраля 2015
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,
    });
0 голосов
/ 23 сентября 2011

Проработав эту проблему и получив предыдущий ответ, я обнаружил некоторые важные детали, отсутствующие в ответе. Наиболее важным моментом здесь является то, что хотя .dialog("destroy") восстанавливает div до его состояния перед инициализацией, он НЕ восстанавливает div в своем первоначальном расположении в DOM. (Вопрос BAHDev упоминает, как UI Dialog перемещает div в первую очередь.) Это критически важно для операции Ajax, и это изменение / неизменение местоположения div должно быть разъяснено в документации jQuery (это спасло бы меня много время).

Если Ajaxing только содержимое диалогового div, то это поведение, вероятно, не критично, так как вы можете легко найти и переписать содержимое div независимо от того, где оно находится в DOM. Однако если содержимое вашего диалога Ajaxed встроено вместе с другими объектами, то перемещение элемента div из его исходного местоположения, вероятно, приведет к тому, что в последующем Ajaxing создаст другой элемент div в исходном местоположении, что приведет к нескольким элементам div с одинаковым идентификатором.

Например, я запрашиваю короткий список продуктов и длинный список продуктов за один вызов Ajax. Краткий список переходит на экран, а длинный список - в скрытый диалог. Поскольку списки связаны, имеет смысл захватить их обоих за один вызов Ajax. Поскольку UI Dialog переместил длинный список из контейнера, в который он был добавлен Ajax, и вставил его в конец тела HTML, когда я запрашиваю новый список, я получаю два элемента div с одинаковым идентификатором, каждый из которых содержит свой длинный список - один в контейнере Ajax и один в конце корпуса. Самый правильный способ, который я вижу, чтобы справиться с этим, это сначала полностью уничтожить старый длинный список, прежде чем Ajaxing новый. (Можно также проверить объекты диалогового окна пользовательского интерфейса и переместить длинный список в коде, но это громоздко и может также потерять атрибуты div.)

При тестировании (jQuery 1.4.4, UI 1.8.10) я обнаружил, что .dialog("destroy") на оригинальном div работает точно так же, как .remove() на родительском div UI Dialog. Таким образом, удаляются только div-оболочки UI Dialog, а исходный 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.

...