Я создаю функциональность на веб-странице, которую пользователь может выполнять несколько раз. В результате действия пользователя объект / модель создается и применяется к HTML с помощью ko.applyBindings ().
HTML-код с привязкой к данным создается с помощью шаблонов jQuery.
Все идет нормально.
Когда я повторяю этот шаг, создавая второй объект / модель и вызывая ko.applyBindings (), я сталкиваюсь с двумя проблемами:
- В разметке отображается предыдущий объект / модель, а также новый объект / модель.
- Возникает ошибка javascript, связанная с одним из свойств объекта / модели, хотя он все еще отображается в разметке.
Чтобы обойти эту проблему, после первого прохода я вызываю jQuery .empty (), чтобы удалить шаблонный HTML, содержащий все атрибуты привязки данных, чтобы его больше не было в DOM. Когда пользователь запускает процесс для второго прохода, HTML-код с привязкой к данным повторно добавляется в DOM.
Но, как я уже сказал, когда HTML повторно добавляется в DOM и повторно привязан к новому объекту / модели, он по-прежнему включает данные из первого объекта / модели, и я все равно получаю ошибку JS, которая не возникает. во время первого прохода.
Вывод, по-видимому, таков, что Knockout сохраняет эти связанные свойства, даже несмотря на то, что разметка удалена из DOM.
Я ищу средство удаления этих связанных свойств из Knockout; говорит нокаут, что наблюдаемой модели больше нет. Есть ли способ сделать это?
РЕДАКТИРОВАТЬ
Основной процесс заключается в том, что пользователь загружает файл; затем сервер отвечает объектом JSON, HTML с привязкой к данным добавляется в DOM, затем объектная модель JSON привязывается к этому HTML с помощью
mn.AccountCreationModel = new AccountViewModel(jsonData.Account);
ko.applyBindings(mn.AccountCreationModel);
После того, как пользователь сделал выбор в модели, тот же объект отправляется обратно на сервер, связанный с данными HTML удаляется из DOM, а затем у меня появляется следующий JS
mn.AccountCreationModel = null;
Когда пользователь желает сделать это еще раз, все эти шаги повторяются.
Боюсь, что код слишком "запутан" для демонстрации jsFiddle.
init
функцию, в которой вы передаете данные для применения?Ответы:
Вы пробовали вызвать метод чистых узлов knockout для своего элемента DOM, чтобы избавиться от связанных с памятью объектов?
Затем повторное применение привязок нокаута только к этому элементу с новыми моделями представления обновит привязку представления.
источник
delete
определенные ключи на самих элементах dom, которые, по-видимому, являются местом, где хранится вся магия нокаута. Если у кого-то есть источник документации, я был бы очень признателен.Для проекта, над которым я работаю, я написал простую
ko.unapplyBindings
функцию, которая принимает узел jQuery и логическое значение удаления. Сначала он отвязывает все события jQuery, посколькуko.cleanNode
метод не заботится об этом. Я проверил утечку памяти, и, похоже, все работает нормально.источник
ko.cleanNode()
вызвано, а не с замененным HTML целиком.Вы можете попробовать использовать привязку with, которую предлагает knockout: http://knockoutjs.com/documentation/with-binding.html Идея состоит в том, чтобы применить привязки один раз, и всякий раз, когда ваши данные изменяются, просто обновляйте свою модель.
Допустим, у вас есть модель представления storeViewModel верхнего уровня, ваша корзина представлена cartViewModel и список элементов в этой корзине - скажем, cartItemsViewModel.
Вы должны привязать модель верхнего уровня - storeViewModel ко всей странице. Затем вы можете разделить части своей страницы, которые отвечают за корзину или элементы корзины.
Предположим, что cartItemsViewModel имеет следующую структуру:
В начале cartItemsViewModel может быть пустым.
Шаги будут выглядеть так:
Определите привязки в html. Отделите привязку cartItemsViewModel.
Модель магазина поступает с вашего сервера (или создается другим способом).
var storeViewModel = ko.mapping.fromJS(modelFromServer)
Определите пустые модели в вашей модели представления верхнего уровня. Затем структура этой модели может быть обновлена фактическими данными.
Свяжите модель представления верхнего уровня.
ko.applyBindings(storeViewModel);
Когда объект cartItemsViewModel доступен, назначьте его ранее определенному заполнителю.
storeViewModel.cartItemsViewModel(actualCartItemsModel);
Если вы хотите очистить корзину:
storeViewModel.cartItemsViewModel(null);
Knockout позаботится о html - то есть он появится, когда модель не пуста, и содержимое div (с пометкой «с привязкой») исчезнет.
источник
Мне нужно вызывать ko.applyBinding каждый раз, когда нажимается кнопка поиска, и отфильтрованные данные возвращаются с сервера, и в этом случае для меня следующая работа без использования ko.cleanNode.
Я испытал, если мы заменим foreach шаблоном, тогда он должен работать нормально в случае коллекций / observableArray.
Вы можете найти этот сценарий полезным.
источник
Вместо использования внутренних функций KO и работы с удалением обработчика событий JQuery, гораздо лучше использовать привязки
with
илиtemplate
. Когда вы это делаете, ko воссоздает эту часть DOM, и поэтому она автоматически очищается. Это также рекомендуемый способ, см. Здесь: https://stackoverflow.com/a/15069509/207661 .источник
Я думаю, что было бы лучше сохранить привязку все время и просто обновить связанные с ней данные. Я столкнулся с этой проблемой и обнаружил, что простой вызов
.resetAll()
метода для массива, в котором я хранил свои данные, был наиболее эффективным способом сделать это.По сути, вы можете начать с некоторой глобальной переменной, которая содержит данные для визуализации через ViewModel:
Мне потребовалось время, чтобы понять, что я не могу просто создать
myLiveData
обычный массив -ko.oberservableArray
деталь была важна.Тогда вы можете идти вперед и делать все, что хотите
myLiveData
. Например,$.getJSON
позвоните:Как только вы это сделаете, вы можете продолжить и применить привязки, используя ViewModel как обычно:
Затем в HTML используйте
myData
как обычно.Таким образом, вы можете просто испортить myLiveData из любой функции. Например, если вы хотите обновлять каждые несколько секунд, просто заключите эту
$.getJSON
строку в функцию и вызовитеsetInterval
ее. Вам никогда не придется снимать привязку, если вы не забудете сохранитьmyLiveData.removeAll();
линию.Если ваши данные не действительно огромны, пользователь даже не сможет заметить время между сбросом массива и последующим добавлением самых последних данных обратно.
источник
Недавно у меня возникла проблема с утечкой памяти, и я
ko.cleanNode(element);
не хотел этого делать -ko.removeNode(element);
сделал. Утечка памяти Javascript + Knockout.js - Как убедиться, что объект уничтожается?источник
Вы думали об этом:
Я придумал это, потому что в Knockout я нашел этот код
Так что для меня это не проблема, которая уже связана, это то, что ошибка не была обнаружена и устранена ...
источник
Я обнаружил, что если модель представления содержит много привязок div, лучший способ очистить их
ko.applyBindings(new someModelView);
- это использовать:ko.cleanNode($("body")[0]);
это позволяетko.applyBindings(new someModelView2);
динамически вызывать новый, не беспокоясь о том, что предыдущая модель представления все еще привязана.источник
$("body")[0]
являетсяdocument.body
.