jQuery document ready with Knockout.js

Chozen picture Chozen · Jul 18, 2014 · Viewed 10.1k times · Source

I just got thrown into the Umbraco ASP.NET CMS for my latest project, I'm not sure if this is how it across the board but for my setup Knockout.js is doing all the templating.

I'm not too keen on knockout.js but so far it's been pretty straight forward except for when I start adding in some jQuery stuff, the problem I'm having is jQuery is firing before knockout has finished populating the page with all the elements.

The only solution that's worked for me thus far is all my jQuery stuff is wrapped in the setTimeout() function, which obviously is no good.

What's the most efficient way to make jQuery and Knockout work together so jQuery doesn't before knockout is done?

Answer

sifriday picture sifriday · Jul 21, 2014

I recently had the same issue with the jSignature plugin and my Knockout view. I needed the KO view to have fully rendered before I invoked jSignature, otherwise it didn't size itself correctly.

I fixed it with a template binding and an afterRender callback function to invoke the jQuery work.

Here's the KO docs:

http://knockoutjs.com/documentation/template-binding.html

Here's a quick jsfiddle showing how you can use it:

http://jsfiddle.net/PCbFZ/

The trick is that you can use the afterRender callback of the template binding without actually using a template itself. Instead, you wrap all your existing HTML in a div that will invoke the afterRender callback:

<div data-bind="template: {afterRender: initApp}">
  <!-- your existing HTML here -->
</div>

initApp is the function that does the jQuery work.

I think that should generally do what you need, though if your HTML is particularly complex, or you have many views you need to render inside the one page, you might need to do a bit more work. Let me know how you get on - maybe I can try to help a bit more if this doesn't quite fix your issue as easily as it did mine!


Update - following the comment from JACL below - here's an extended version of the fiddle showing this technique also working with ko-if. Each time you show/hide the 'widget' using the checkbox, a different random colour is applied to indicate the afterRender function doing its work.

http://jsfiddle.net/PCbFZ/15/