Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout js - beforeRemove animation while adding items to observable array

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> 
like image 418
Cyriuz Avatar asked Feb 12 '13 08:02

Cyriuz


1 Answers

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); }); 
like image 183
adil.hilmi Avatar answered Sep 23 '22 00:09

adil.hilmi