O componente Knockout falha se o elemento for removido antes do modelo retornar
Eu tenho uma ligação personalizada KO que adiciona um componente à página (como um elemento virtual, mas acho que isso não importa) e, em seguida, aplica um modelo de exibição a ele. O componente carrega seu modelo via require do servidor.
No entanto, durante o carregamento, estou tendo um problema em que a ligação personalizada é atualizada e removendo o elemento da página (eu quero que ele seja arrumado, se não for necessário).
Isso resulta em uma condição de corrida - se a pesquisa assíncrona do modelo não tiver sido concluída antes que os elementos sejam removidos quando o KO tentar aplicar o componente, ele não poderá encontrar a tag de fechamento e gerará um erro.
Gostaria de saber se há algo que alguém possa sugerir para aliviar o problema? Eu já sei que não há mecanismo de retorno de chamada emapplyBindings
e eu nãopensar afterRenderCallback
ajudará, pois erros antes que cheguem tão longe. Gostaria de saber se existe uma maneira decancelar, interromper ou interromper o processo e não há.
Alguma ideia?
Aqui está umviolino o que demonstra meu problema.
Minha ligação personalizada é assim:
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");
}
}
}
}
Ele está fazendo chamadas para uma classe de controlador que se parece com isso:
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);
}
O componente é carregado via exigem:
ko.components.register("my-component", {
//template: "<p data-bind=\"text: message\"></p>"
template: { require: "text!component-template" }
});
E uma inicialização simplificada é mais ou menos assim:
var vm = { shouldBeBound: ko.observable(true) };
ko.applyBindings(vm);
vm.shouldBeBound(false);
Na realidade, tenho algumas dependências mais complexas que definem o sinalizador como false após o início da inicialização.