solefald
solefald

Reputation: 1799

KnockoutJS: Execute template in a newly appended DOM element

I have a large data object that generates a table with lots of long drop down menus. This takes forever, so I am trying to speed up rendering of the table by not rendering all drop down menus on initial load. Instead, I just want to render each menu on demand/click.

// HTML Element
<button class="btn dropdown-toggle" data-toggle="dropdown" data-bind="click: getTags">Tag</button>
<ul class="dropdown-menu">
    // Some HTML here
</ul>

// KO Template
<script type="text/html" id="alltags">
    <a href="#" data-bind="text: $data"></a>
</script>

// JS Code
self.getTags = function(data, event) {
    self.availableTags(data.component.available_tags())
    $(event.target).parent().find('ul').prepend('<li data-bind="template: { name: alltags, data: availableTags }"></li>')
}

The issue I am having it that DOM element gets prepended to the div as I want it to, but for the life of me I can not get it to execute the foreach: loop and generate the menu contents.

Do i need to refresh bindings?

Upvotes: 0

Views: 97

Answers (1)

QBM5
QBM5

Reputation: 2788

The apply bindings will not fire when you add html that way, what I would do is.

Create the dropdowns on load and bind the options to an empty array, when the click event fires populate the empty array with the desired data.

addtl.....

you could create a template that creates your dropdowns and loads them, then do something like this

<!--   ko foreach: templates -->

  <div data-bind:template:{name: tmpl, data:data}></div>
<!--     /ko  -->

then use a setTimeout to only load a few at a time, it will still take a while, but will bog down you UI less.

function recursive(){
setTimeout(function(){
  // load 5 templates into template array
  check if there are more left, call recursive function to add more
 },50);
}

get a little complicated but I have done similar things to fix UI lag in the past

Upvotes: 1

Related Questions