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.
applyBindings do, The first parameter says what view model object you want to use with the declarative bindings it activates. Optionally, you can pass a second parameter to define which part of the document you want to search for data-bind attributes. For example, ko.
unwrapObservable(item) Looking at the code, that call basically checks to see if item is an observable. If it is, return the value(), if it's not, just return the value.
An observable is useful in various scenarios where we are displaying or editing multiple values and require repeated sections of the UI to appear and disappear as items are inserted and deleted. The main advantage of KO is that it updates our UI automatically when the view model changes.
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.
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-->
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With