I have a KnockoutJS template that looks something like this:
<div data-bind="template: {name: 'testTemplate', data: people}"></div>
<script id="testTemplate" type="text/html">
<!--ko foreach: $data-->
<div class="items" data-bind="text: full() + ' updated at: ' + Date()"></div>
<!--/ko-->
</script>
After running Nth number of tests, I realized that creating a template like this is flawed as KnockoutJS will update the template every single time, even if the data doesn’t change.
I’ve illustrated this using these two fiddles:
- using the foreach binding (works correctly)
- using the data binding (fails horribly)
As you can see, if you pound the load initial, or load updated data buttons on the foreach binding, the UI is never re-rendered unless the data actually changes. Unfortunately if you do the same on the data style binding, it’s re-rendered every time.
I really can’t figure out what the difference is. I was under the impression that the data binding worked the same way as foreach, but allowed more control of the object inside of the template.
The only reason I’m using it is because I have a set of nested templates, and I needed to get closer to the actual object at hand. I should be able to re-factor, and get away from that approach, but I’m still left wondering why it’s an issue.
Shouldn’t the <!--ko foreach:--> honor the same pattern that the foreach template binding uses?
The issue is that your template binding creates a subscription to your
peopleobservableArray as it is passed as thedata. When thepeoplearray is updated (items pushed/removed, etc.), then this will trigger the template binding to re-render the template. In your case, this re-renders all of the content, so theforeachinside of the template never gets a chance to be efficient.An easy way to avoid this is to make sure that the template binding does not unwrap your
peopleobservableArray. You can pass the data like{ myArray: people }and then do yourforeachonmyArray.Here is a sample: http://jsfiddle.net/rniemeyer/bVPwM/4/