I have an AJAX MVC Contrib Grid implementation, that already existed and now I am in a situation where I am trying to bolt on some knockout functionality... and I want to know if this is possible without changing the whole grid implementation.
This is the refresh grid function that is setting the container html when the pagination changes.
scope.refreshGrid = function (container, url) {
if (url)
container.data(scope.selectors.actionUrlAttribute, url);
$.post((url || container.data(scope.selectors.actionUrlAttribute)), scope.getParams(),
function(html) {
container.html($(html).html());
scope.bindDeleteButtons();
}).done(function() {
container.trigger("refresh.ctb.grid");
});
}
one of the columns for the grid is custom column that uses Html.Partial
like this:
column.Custom(x => Html.Partial("_CartSelection", new CartSelection(x.Id)));
The partial view has the below markup with some knockout data bindings
<input type="checkbox" value="@Model.Id" data-bind="enable: (selectionEnabled() || $element.checked), checked: selectionIds" />
This works for the first page of results, when the paging is selected to change the page and the container html() is updated the bindings no longer work but the KO viewModel still has the correct selectionIds
.. which is what I was expecting to happen.
The KO view model is being applied as shown below, where the grid has a wrapper parent div
with an id
of "cart":
$(function() {
var viewModel = new IP.Configuration.CartSelector(new IP.Router());
ko.applyBindings(viewModel, document.getElementById("cart"));
});
I have already seen comments in other posts about how you shouldn't re-apply bindings. In my case it seems I want to apply bindings but only to some child nodes that are being dynamically loaded.
Is this possible?
UPDATE:
Almost had this working by adding a cart-selection
class to each checkbox and doing the below in a rebind
function on the viewModel, where self
is the viewModel:
$("#cart .cart-selection").each(function(index, item) {
ko.applyBindings(self, item);
});
Then doing the below on the custom trigger for refreshing the grid, when the content is reloaded.
$("#cartGrid").on("refresh.ctb.grid", function() {
viewModel.rebind();
});
The issue I am finding with this at the moment is that the checkboxes are no longer enabled regardless of the $element.checked
binding.. maybe a valueHasMutated will fix this, still looking into this.
I figured out what my remaining problem was, it was due to the ordering of the data bindings.
The enable
data bind needed to be placed after the checked
binding since it has a dependency on it via $element.checked
which makes sense now after realising it!!
I changed my rebind function slightly to the below:
var gridResult = $("#cartGrid table");
if (gridResult.length > 0)
ko.applyBindings(this, gridResult[0]);
Each refresh brings in a new table but at least now if I add any more bindings to other elements in the results from the grid, they will work as expected.