Как удалить все элементы Kendo DropDownList из document.body (DOM)

Мы используем около 3 компонентов DropDownList внутри элемента cardView kendo.ui.Window. Когда окно закрывается, мы вызываем метод «уничтожить» для каждого из содержащихся элементов DropDownList.

Проблема в том, что следующий код не удаляет все элементы DIVS, связанные с DropDownList, которые были добавлены к телу документа:

var dropdownlist = $("#dropdownlist").data("kendoDropDownList");
dropdownlist.destroy();

После некоторых поисков мы заметили следующий комментарий в документации к методу destroy (от Telerik): Важно: этот метод не удаляет элемент DropDownList из DOM.

Поэтому каждый раз, когда кто-то открывает и закрывает окна нашего кендо (представление карты), многие элементы div DropDownList добавляются без удаления из DOM — это может вызвать серьезные проблемы с производительностью в DOM.

Добавленные DIVS, которые остаются в DOM, например, «k-list-container» и «k-animation-container».

  1. Как я могу решить эту проблему?
  2. Есть ли способ полностью уничтожить каждый элемент DropDownList (включая удаление всех связанных с ним элементов из DOM)?
  3. Актуальна ли эта проблема, когда нам нужно уничтожить другие компоненты kendo.ui? (такие как поле со списком, dateTimePicker, всплывающая подсказка и т. д.) Так как наше окно карты kendo.ui также содержит другие основные компоненты kendo.ui.

person AmirTNinja    schedule 25.06.2014    source источник
comment
Я думаю, что k-animation-container имеет идентификатор раскрывающегося списка с добавленным к нему -list. (используя ваш пример: id="dropdownlist-list")   -  person Pedro Estrada    schedule 25.06.2014


Ответы (2)


Метод destroy удалит элементы, которые добавляются к телу документа и которые нельзя явно связать с виджетом, просто взглянув на DOM. Так, например, элемент с классом k-animation-container убран для выпадающих списков. В комментарии к документации говорится, что элементы на месте не удаляются.

Для того, чтобы удалить все, вы должны вызвать уничтожение виджета, а затем самостоятельно удалить оставшиеся элементы. Самый простой вариант — создать обертку вокруг всех виджетов, которые вы хотите уничтожить, и удалить их. Если вы хотите удалить конкретный виджет, обычно вы также можете сослаться на свойство wrapper, которое содержит элемент jQuery, представляющий самый внешний элемент DOM этого виджета:

$(widget.wrapper).remove();

поэтому в вашем случае это удалит все элементы и события для раскрывающегося списка:

var dropdownlist = $("#dropdownlist").data("kendoDropDownList");
dropdownlist.destroy();
dropdownlist.wrapper.remove();

Если вы хотите удалить все, что вы создали для окна кендо, вы можете сделать то же самое:

var window = $("#window").data("kendoWindow");
// recursively call destroy for all widgets it finds
kendo.destroy(window.wrapper); 
window.wrapper.remove();
person Lars Höppner    schedule 25.06.2014
comment
Спасибо за ответ. Попробую обертку.удалить. Тем не менее, я не понял в вашем ответе какой-то способ - как я могу сделать так, чтобы все наши оконные виджеты (которые нужно уничтожить) находились под каким-то оберточным div? Например, когда мы создаем DropDownList, его div-владелец — это какой-то div внутри окна кендо, а сам компонент dropDownList добавляет некоторые дополнительные управляемые div в document.body (все div k-animation-container и k-list-container, которые представляют всплывающую панель раскрывающегося списка, я собрал). - person AmirTNinja; 25.06.2014
comment
Я пробовал dropdownlist.wrapper.remove() - но это не сработало. разделы «k-list-container» не были удалены из document.body. Кроме того, я проверил dropdownlist.wrapper в режиме отладки (инструменты разработчика Chrome) и заметил, что dropdownlist.wrapper указывал на элементы «.k-dropdown», которые находятся под окном div, и не указывал ни на один внешних (тело .k-list-container) разделов. - person AmirTNinja; 25.06.2014
comment
k-list-container является потомком k-animation-container, и он будет удален с помощью widget.destroy(); проверьте это: jsfiddle.net/lhoeppner/mEf4N - person Lars Höppner; 25.06.2014
comment
По какой-то причине, даже когда мы вызываем widget.destroy(), контейнер k-list-container/k-animation-container все еще существует в document.body. Кажется, что мы наблюдаем случай, противоположный примеру jsfiddle. наша веб-страница (разработанная под angularJS + машинописный текст) div dropDownList удаляется из DOM (после вызова widget.destory), а не связанный с ним Div k-list-container/k-animation-container ( который находится под document.body). Что может вызвать этот сценарий? может ли это быть как-то вызвано фреймворком AngularJS? - person AmirTNinja; 26.06.2014
comment
Вы используете угловое кендо? трудно помочь, не видя кода - если возможно, попробуйте создать минимальную демонстрацию (plnkr/jsbin) - person Lars Höppner; 26.06.2014
comment
да, очень сложно создать минимальную демонстрацию, которая воссоздает эту проблему, но мы проверим ее. Но в целом, без учета angularJS, может ли быть какая-либо другая причина, которая может быть причиной вышеуказанной проблемы? что вызывает противоположный сценарий jsfiddle, который вы связали? - person AmirTNinja; 26.06.2014
comment
ничего не могу придумать банкомат, извините; какую версию Kendo UI вы используете? может быть ошибка в этой версии (или angular-kendo); Я бы также дважды проверил, что вы вызываете .destroy для виджетов, которые, по вашему мнению, вы вызываете. - person Lars Höppner; 26.06.2014
comment
Может ли это быть связано с тем, что в нашем сценарии компоненты dropDownList создаются внутри оконного компонента kendo.ui, который закрывается и уничтожается? (вместе с элементами dropDownList внутри него) - person AmirTNinja; 26.06.2014
comment
раскрывающийся список должен быть уничтожен, когда вы уничтожаете окно в этом случае; Я бы исследовал, действительно ли контейнер k-animation принадлежит раскрывающемуся списку в вашем окне или он из другого раскрывающегося списка. - person Lars Höppner; 26.06.2014

По какой-то причине ни одно из предыдущих решений не сработало для меня, и это то, что я в итоге реализовал.

var grid = $('#GridName').data("kendoGrid");

//get grid data
var gridData = grid.dataSource.data();

//set the length (cannot use data.length in for loop as it changes when you remove the data items)
var dataLength = gridData.length;

//remove data from the grid
if (dataLength > 0) {
    for (var i = 0; i < dataLength; i++) {
        //must delete the first object in the array else it throws index out of bounds 
        //error because the data array changes when you remove an object
        grid.dataSource.remove(data[0]);
    }
}
person Time2Panic    schedule 28.02.2017
comment
Вы можете использовать приведенный ниже код, чтобы предотвратить выход индекса за пределы var oldData = grid.dataSource.data(); for (var i = oldData.length - 1; i >= 0; i--) { comboBox.dataSource.remove(oldData[i]); } - person chinh nguyen van; 19.06.2018