knockout.js - Knockout + Datatables - update bindings in cells -
i using josh buckley's datatables binding knockout. i'm trying create "delete row" button in datatable. have click data-bind on each button. datatable source hooked observable array. when user clicks on button, object removed observable array, triggers update binding, , table view subsequently gets updated. works fine, @ least first time click on button.
however, once the table updated, of click bindings on "delete row" buttons stop working. presume because entire table cleared , rebuilt each time update binding called, , bindings aren't applied on new elements.
how can rebind new elements generated each datatable update? alternatively, there better way handle this?
custom binding:
(function($){ ko.bindinghandlers.datatable = { init: function(element, valueaccessor){ var binding = ko.utils.unwrapobservable(valueaccessor()); // if binding object options field, // initialise datatable options. if(binding.options){ $(element).datatable(binding.options); } }, update: function(element, valueaccessor){ var binding = ko.utils.unwrapobservable(valueaccessor()); // if binding isn't object, turn one. if(!binding.data){ binding = { data: valueaccessor() } } // clear table $(element).datatable().fncleartable(); // rebuild table data source specified in binding $(element).datatable().fnadddata(binding.data()); } }; })(jquery);
html code:
<table id="memberstable" class="table table-striped table-bordered bootstrap-datatable datatable" data-bind="datatable: memberstable"> <thead> <tr> <th>name</th> <th>actions</th> </tr> </thead> </table>
view model:
var groupviewmodel = { groupmembers: ko.observablearray([ new groupmember("1", "abe", true), new groupmember("2", "bob", false), new groupmember("3", "bill", false) ]) }; groupviewmodel.memberstable = ko.computed(function() { var self = this; var final_array = new array(); for(var = 0; < self.groupmembers().length; i++) { var row_array = new array(); row_array[0] = self.groupmembers()[i].namewithlink(); row_array[1] = self.groupmembers()[i].actions(); final_array.push(row_array); } return final_array; }, groupviewmodel); groupviewmodel.removemember = function(id) { var self = this; self.groupmembers.remove(function(groupmember) { return groupmember.id == id; }); };
group member object:
function groupmember(id, name, isgroupleader) { var self = this; self.id = id; self.name = name; self.isgroupleader = ko.observable(isgroupleader); self.link = ko.computed(function() { return "/#user/" + self.id; }); self.namewithlink = ko.computed(function() { return '<a href="' + self.link() + '">' + self.name + '</a>'; }); self.actions = ko.computed(function() { return '<a class="btn btn-danger" data-bind="click: function() {removemember(' + self.id + ')}">' + '<i class="icon-minus-sign"></i>' + '</a>'; }); }
edit:
jsfiddle link: http://jsfiddle.net/zongweil/plukv/1/
i not sure buckley guys data table binding there lot of problems in original fiddle posted touch on can see why solution posted works , better method -
don't create array of arrays give data functionality (such remove or linking). bad practice , setting problems. can either use generic method put viewmodel add functionality data record or can use plethora of other methods - don't add html in view model.
you don't need foreach data in view model add functionality. knockout helping giving tools need in view view model has know nothing view. also, don't put view model functionality view - it's bad practice (you had function injected html, thats dirty!)
finally, don't put view model functionality model - view model for!
your view faster , more efficient @ rendering - let it's job -
<tbody data-bind="foreach: groupmembers"> <tr> <td><a data-bind="click: $parent.gotopersonlink, text: name" /></td> <td><button data-bind="click: $parent.removemember"><i class="icon-remove" /></button></td> </tr> </tbody>
give view model opportunity provide functionality without having inject html -
self.removemember = function (member) { self.groupmembers.remove(member); }; self.gotopersonlink = function (member) { alert('add change window logic here'); };
you add functionality model, such removing member, means if have 1000 records code runs 999 more times needs to. being said, if absolutely have go old way of doing it, luck! if case rid of dependency knockout because don't need it.
Comments
Post a Comment