Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there some sort of callback available on ko.applyBindings?

Tags:

knockout.js

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.

like image 438
connexo Avatar asked Aug 25 '15 14:08

connexo


People also ask

What is applyBindings in knockout?

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.

What does Ko unwrap do?

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.

What does Ko observable do?

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.


2 Answers

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.

like image 110
Dandy Avatar answered Oct 28 '22 05:10

Dandy


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-->
like image 26
TSV Avatar answered Oct 28 '22 07:10

TSV