Is there some sort of callback available on ko.app

2019-04-08 18:17发布

问题:

Using knockout.js on our current project, we came to this point several times already.

How can I make sure some piece of Javascript code gets executed only after all bindings on the page have been applied by Knockout?

In my specific use case, I am using if-bindings to evaluate some configuration options and decide whether the elements inside should be rendered (= in the DOM) or not. Only after these if-bindings have been evaluated I need to count the number of DOM nodes inside a certain element. Obviously, if I count too early the if-bindings have not removed those unwanted DOM nodes yet, so the counting comes to a wrong result.

回答1:

May be this will be helpful. You can wrap your binding with template binding (and put any another binding(s) inside the template) and pass the 'afterRender' handler. This handler will be called after content will have been rendered. I've beautified the jsfiddle mentioned above (in the comment):

var model = {
  afterRenderCallback: function() {
    // this method will be called after content rendered
    var divContent = document.getElementById("textdiv").innerHTML;
    alert(divContent);
  },
  txt: ko.observable("this text will be substituted in the div")
};

ko.applyBindings(model);
.content {
    border: 1px solid red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<script type="text/html" id="wrappingTemplate">
<div id="textdiv" class="content" data-bind="text: txt"></div>
</script>

<!-- ko template: { name: 'wrappingTemplate', afterRender: afterRenderCallback } -->
<!-- /ko-->



回答2:

ko.applyBindings() is a synchronous call, so the next statement should be only executed after it's done. If you have knockout components, they can either be loaded synchronously or asynchronously. So, for example

var vm = new ViewModel();
ko.applybindings(vm);
//
CountRenderedElements();

should give you correct result.



标签: knockout.js