Reputation: 590
I have hooked up several components: Knockout, jQuery DataTables + custom KnockOut DataTables, Bootstrap pagination etc. It's is based on this example: http://chadmullins.com/javascript/knockout-js-series-part-2-binding-knockout-js-to-a-datatables-grid/
Now, this all works perfectly - until I click on one of the controls of the pagination. It seems that somehow the "enable" binding breaks.
This is the binding:
<button data-bind="click: $parent.AddToCart, enable: !$parent.InBasket($data)">Add</button>
Forgive me for linking to a Fiddle, but regarding the dependencies I think this is the easiest way for demonstrating the "problem". Fiddle: http://jsfiddle.net/K8hhx/
Anybody seen this before?
Upvotes: 2
Views: 3525
Reputation: 7342
You have a subtle, but common problem in using knockout.
The problem is in the $parent.InBasket($data)
function call as below.
<td>
<button class="btn btn-mini btn-primary" type="button"
data-bind="click: $parent.AddToCart,
enable: !$parent.InBasket($data)">
Add</button>
</td>
The problem is that the function is not is not an observable. While it looks okay, it can causes problems like you are seeing.
I changed the html to be
<td>
<button class="btn btn-mini btn-primary" type="button"
data-bind="click: $parent.AddToCart, enable: !InBasket()">Add</button>
</td>
And the item data model is -
var CartItem = function(name) {
var self = this;
self.Name = ko.observable(name);
self.InBasket = ko.observable(false); /// NEW
}
By putting the InBasket in the item datamodel, when it's status is updated, knockout knows how to update the screen as you page. From a performance point of view, it is faster because every time the screen is redrawn, you no longer have to search the cart to see is in it.
Updated at http://jsfiddle.net/photo_tom/K8hhx/4/. Actual code changes are fairly small.
BTW: I'm thinking of using this Datatables/Knockout in an upcoming project have having a real sample to look at will be useful.
Upvotes: 2