0
votes

I have specified a afterAdd binding so that when I'm adding a item to a observableArray I get a pretty slideDown effect. Works great, looks cool.

Problem is on the initial load. I'm loading from a data source and setting the observableArray to the returned json data. Imagine 20 items on the screen all sliding down at the same time. Not so cool. How can I stop that from happening?

Slide function:

vm.addItem = function (elem) {
    if (elem.nodeType === 1) { $(elem).hide().slideDown(); }
};

Looks nice when adding a single item:

vm.postComment = function () {
    $.post('Place/PostComment', { placeId: vm.placeId(), comment: vm.comment() }, function (comment) {
        vm.comments.push(comment);
        vm.comment('');
    });
};

Not so nice when setting the initial value. Sliding down for each added:

vm.loadPlace = function () {
    $.getJSON('Place/GetComments', { placeId: vm.placeId() }, function (data) {
        vm.comments(data.Comments);
    });
};

Update 11/16/2012 Morning

From Vyacheslav Voronchuk's suggestion my HTML looks like this:

<ul id="placeComments" data-bind="foreach: { data: comments, afterAdd: addItem, afterRender: renderedComments, beforeRemove: removeItem }">

Javascript looks like this:

vm.renderedComments = function () {
    loading = false;
};

vm.addItem = function (elem) {
    if (!loading) {
        if (elem.nodeType === 1) {
            $(elem).hide().slideDown();
        }
    }
};

vm.loadPlace = function () {
    $.getJSON('Place/GetPlace', { placeId: vm.placeId() }, function (data) {
        loading = true;
        vm.comments(data.Comments);
    });
};

Still seeing the animation. Using the debugger I can see that it enters the addItem function twice.

On a side note I'm guessing this is why the documentation uses fadeIn instead of slideDown. Maybe I should switch...

1

1 Answers

0
votes
vm.loadPlace = function () {
    $.getJSON('Place/GetComments', { placeId: vm.placeId() }, function (data) {
         vm.loading = true;
         vm.comments(data.Comments);
    });
};

vm.addItem = function (elem) {
   if (elem.nodeType === 1) { 
      if(!vm.loading) {
         $(elem).hide().slideDown(); 
      }
   }
};

In your view, add afterRender where you will set vm.loading = false.