javascript - How to detect moving of an item between knockout observable arrays -
javascript - How to detect moving of an item between knockout observable arrays -
i building web-abb using query , knockout. on page have couple of lists of items. these lists sortable , connected, far jquery goes working ok. have used ryan niemeyer's illustration create custom binding sortables update view-model's observable arrays.
this works quite nicely want save changes back-end server. using subscriptions on observable arrays can observe item removed from, , added array leads 2 update calls back-end server.
if goes wrong during 1 of these calls backend in invalid state.
how 1 go detecting removal of item , subsequent adding of same item web-application can create 1 move-call back-end server?
i think way handle add together callback alternative sortablelist binding passes item, original parent, , new parent arguments.
here binding using ko 2.0 might callback:
//connect items observablearrays ko.bindinghandlers.sortablelist = { init: function(element, valueaccessor, allbindingsaccessor, data, context) { var options = ko.utils.unwrapobservable(valueaccessor()); //attach appropriate class our element if (ko.bindinghandlers.sortablelist.autoaddclass) { ko.utils.toggledomnodecssclass(element, ko.bindinghandlers.sortablelist.defaultclass, true); } $(element).data("sortlist", options.list || valueaccessor()); //attach meta-data $(element).sortable({ update: function(event, ui) { var item = ui.item.data("sortitem"); if (item) { //identify parents var originalparent = ui.item.data("parentlist"); var newparent = ui.item.parent().data("sortlist"); //figure out new position var position = ko.utils.arrayindexof(ui.item.parent().children(), ui.item[0]); if (position >= 0) { originalparent.remove(item); newparent.splice(position, 0, item); } ui.item.remove(); if (options.afterdrop) { options.afterdrop.call(this, item, newparent, originalparent); } } }, connectwith: '.' + ko.bindinghandlers.sortablelist.defaultclass }); homecoming ko.bindinghandlers.template.init.apply(this, arguments); }, update: function(element, valueaccessor, allbindingsaccessor, data, context) { var options = ko.utils.unwrapobservable(valueaccessor()), newoptions = {}; //build our options pass template engine if (options.list) { newoptions.foreach = options.list; newoptions.name = options.tmpl; newoptions.includedestroyed = options.includedestroyed; newoptions.afteradd = options.afteradd; newoptions.beforeremove = options.beforeremove; } else { newoptions.foreach = valueaccessor(); } //use afterrender function add together meta-data if (options.afterrender) { //wrap existing function, if passed newoptions.afterrender = function(element, data) { ko.bindinghandlers.sortablelist.afterrender.call(data, element, data); options.afterrender.call(data, element, data); } } else { newoptions.afterrender = ko.bindinghandlers.sortablelist.afterrender; } //call actual template binding ko.bindinghandlers.template.update(element, function() { homecoming newoptions; }, allbindingsaccessor, data, context); }, afterrender: function(elements, data) { ko.utils.arrayforeach(elements, function(element) { if (element.nodetype === 1) { $(element).data("sortitem", data); $(element).data("parentlist", $(element).parent().data("sortlist")); } }); }, defaultclass: 'container', autoaddclass: true };
you specify binding like:
<ul data-bind="sortablelist: { tmpl: 'myitems', list: myobservablearray, afterdrop: mycallback }"></ul>
now, can add together own callback tells server item moved. observablearrays functions (which objects), can assign properties them. here sample assigned id
property each observable array , access in callback, have friendly way of knowing 1 old parent , new parent:
http://jsfiddle.net/rniemeyer/qzscp/
javascript jquery jquery-ui knockout.js
Comments
Post a Comment