I have a problem with knockout js and displaying an observable array as a list; When adding an item while the beforeRemove animation is running, the removed element is moved to the bottom of the list instead of staying in its position until the animation has finished and the element is removed.
Here is a jsfiddle to explain the problem a little better: http://jsfiddle.net/bPP5Q/8/
Anyone know how i could solve this?
javascript:
jQuery(function ($) { var ViewModel = function (data) { var self = this; self.data = ko.observableArray(data); self.removeLine = function (elem) { if (elem.nodeType === 1) $(elem).fadeOut(3000, function () { $(elem).remove(); }); } self.addLine = function (elem) { if (elem.nodeType === 1) $(elem).hide().fadeIn(3000); } self.removeItem = function() { self.data.remove(function(item) { return item.test && item.test == 2; }); } self.addItem = function() { self.data.splice(1, 0, { test: 9 }); } self.addremove = function () { self.removeItem(); var id = setInterval(function() { self.addItem(); clearInterval(id); },1000); } } var vm = new ViewModel([{ test: 9 }, { test: 2 }, { test: 1 }, { test: 1 }, { test: 1 }, { test: 1 }, { test: 1 }]); ko.applyBindings(vm); });
HTML:
<button id="button" data-bind="click: addremove">Click</button> <table id="grid"> <tbody data-bind='template: { foreach: data, afterAdd: addLine, beforeRemove: removeLine }'> <tr> <td data-bind="text: test"></td> <td> </td> </tr> </tbody> </table>
Your function "addItem" is executed after 1 second (setInterval 1000 ms) so the "self.data" contains a new element while the animation fadeout is not complete (that's require 3000 ms). That's explicate your problem.
To resolve this problem you must make the same interval for "addItem" as the "fadeout", for your exemple it's 3000. The code becomes :
jQuery(function ($) { var ViewModel = function (data) { var self = this; self.data = ko.observableArray(data); self.removeLine = function (elem) { if (elem.nodeType === 1) $(elem).fadeOut(3000, function () { $(elem).remove(); }); } self.addLine = function (elem) { if (elem.nodeType === 1) $(elem).hide().fadeIn(3000); } self.removeItem = function() { self.data.remove(function(item) { return item.test && item.test == 2; }); } self.addItem = function() { self.data.splice(1, 0, { test: 9 }); } self.addremove = function () { self.removeItem(); var id = setInterval(function() { self.addItem(); clearInterval(id); },3000); // the same interval as the "fadeout" } } var vm = new ViewModel([{ test: 9 }, { test: 2 }, { test: 1 }, { test: 1 }, { test: 1 }, { test: 1 }, { test: 1 }]); ko.applyBindings(vm); });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With