Knockout-Komponente schlägt fehl, wenn das Element vor der Rückgabe der Vorlage entfernt wurde

Ich habe eine benutzerdefinierte KO-Bindung, die der Seite eine Komponente hinzufügt (als virtuelles Element, aber ich glaube nicht, dass dies von Bedeutung ist) und dann ein Ansichtsmodell darauf anwendet. Die Komponente lädt ihre Vorlage über require vom Server.

Während des Ladevorgangs tritt jedoch ein Problem auf, bei dem die benutzerdefinierte Bindung aktualisiert und das Element von der Seite entfernt wird (ich möchte, dass es aufgeräumt wird, wenn es nicht erforderlich ist).

Dies führt zu einer Race-Bedingung. Wenn die asynchrone Suche nach der Vorlage nicht abgeschlossen ist, bevor die Elemente entfernt wurden, wenn KO versucht, die Komponente anzuwenden, kann das schließende Tag nicht gefunden werden, und es wird ein Fehler ausgegeben.

Ich frage mich, ob jemand etwas vorschlagen kann, um das Problem zu lindern. Ich weiß bereits, dass es auf @ keinen Rückrufmechanismus gibapplyBindings und ich nichtdenke afterRenderCallback wird helfen, da es Fehler gibt, bevor es so weit kommt. Ich habe mich gefragt, ob es einen Weg zu @ gibabbrechen, stoppen oder abbrechen und es gibt keine.

Irgendwelche Ideen

Hier ist einGeig was mein Problem zeigt.

Meine benutzerdefinierte Bindung sieht folgendermaßen aus:

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");
        }
      }
    }
  }

Es ruft eine Controller-Klasse auf, die folgendermaßen aussieht:

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);
  }

Die Komponente wird geladen über require:

  ko.components.register("my-component", {
    //template: "<p data-bind=\"text: message\"></p>"
    template: { require: "text!component-template" }
  });

Und eine vereinfachte Initialisierung sieht ungefähr so aus:

  var vm = { shouldBeBound: ko.observable(true) };

  ko.applyBindings(vm);

  vm.shouldBeBound(false);

In Wirklichkeit habe ich einige komplexere Abhängigkeiten, die das Flag nach Beginn der Initialisierung auf false setzen.

Antworten auf die Frage(2)

Ihre Antwort auf die Frage