Компонент Knockout завершается неудачно, если элемент удален до возвращения шаблона
У меня есть пользовательская привязка KO, которая добавляет компонент на страницу (как виртуальный элемент, но я не думаю, что это имеет значение), а затем применяет к нему модель представления. Компонент загружает свой шаблон с помощью require с сервера.
Однако во время загрузки я получаю проблему, когда пользовательская привязка обновляется и удаляется элемент со страницы (я хочу, чтобы он был аккуратным, если он не требуется).
Это приводит к состоянию гонки - если асинхронный поиск шаблона не завершен до того, как элементы удалены, когда KO пытается применить компонент, он не может найти закрывающий тег и выдает ошибку.
Мне интересно, есть ли что-нибудь, что кто-нибудь может предложить, чтобы облегчить проблему? Я уже знаю, что нет механизма обратного вызова наapplyBindings
и я несчитать afterRenderCallback
поможет, так как это ошибки, прежде чем он зайдет так далеко. Я задавался вопросом, есть ли способотменить, остановить или прервать процесс и нет
Есть идеи?
Вотиграть на скрипке который демонстрирует мою проблему.
Моя пользовательская привязка выглядит так:
ko.bindingHandlers.customBinding = {
update: function(element, valueAccessor){
var $element = $(element)
if(ko.unwrap(valueAccessor())){
$element.data("controller", new CustomBindingController(element));
} else {
var controller = $element.data("controller");
if(controller){
controller.destroy();
$element.removeData("controller");
}
}
}
}
Это делает вызовы к классу контроллера, который похож на это:
function CustomBindingController(element){
var self = this,
$element = $(element),
$component;
function init(){
$component = $("<!-- ko component: { name: \"my-component\", params: $data } --><!-- /ko -->");
$("#component-container").append($component);
ko.applyBindings( { message: "Binding Applied!" }, $component[0]);
self.destroy = destroy;
}
function destroy(){
$component.remove();
}
init.call(self);
}
Компонент загружается через require:
ko.components.register("my-component", {
//template: "<p data-bind=\"text: message\"></p>"
template: { require: "text!component-template" }
});
И упрощенная инициализация выглядит примерно так:
var vm = { shouldBeBound: ko.observable(true) };
ko.applyBindings(vm);
vm.shouldBeBound(false);
На самом деле у меня есть несколько более сложных зависимостей, которые устанавливают флаг в false после начала инициализации.