Как остановить анимацию для начальной загрузки при использовании Knockout.js с привязкой foreach и 'afterAdd'

Я указал привязку afterAdd, поэтому при добавлении элемента в observableArray я получаю красивый эффект slideDown. Отлично работает, круто выглядит.

Проблема в начальной загрузке. Я загружаю из источника данных и устанавливаю observableArray для возвращаемых данных json. Представьте себе 20 элементов на экране, которые одновременно скользят вниз. Не так уж круто. Как я могу предотвратить это?

Функция слайда:

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

Выглядит красиво при добавлении одного элемента:

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

Не так приятно при установке начального значения. Скользя вниз для каждого добавленного:

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

Обновление от 16 ноября 2012 г., утро

По предложению Вячеслава Ворончука мой HTML выглядит так:

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

Джаваскрипт выглядит так:

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);
    });
};

До сих пор смотрю анимацию. Используя отладчик, я вижу, что он дважды входит в функцию addItem.

Кстати, я предполагаю, что именно поэтому в документации используется fadeIn вместо slideDown. Может быть, я должен переключиться...


person rball    schedule 16.11.2012    source источник


Ответы (1)


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(); 
      }
   }
};

В вашем представлении добавьте afterRender, где вы установите vm.loading = false.

person Vyacheslav Voronchuk    schedule 16.11.2012
comment
Похоже, что он дважды проходит через addItems, один раз, когда загрузка имеет значение true, но затем возвращается после того, как оно становится ложным. Не уверен, что у меня что-то не так с моим кодом или почему он это делает, но обновлю свой ответ своим последним кодом. - person rball; 16.11.2012
comment
Пока я просто собираюсь переключиться на fadeIn. Я думал, что ваш ответ сработает, но не уверен, как обойти то, как addItem вызывается как при первой инициализации foreach, так и при добавлении новых записей в связанный массив позже. (из документации) - person rball; 16.11.2012
comment
Не могли бы вы показать, как вы инициализируете наблюдаемый массив comments? - person Vyacheslav Voronchuk; 17.11.2012
comment
Я могу предложить вам использовать опцию .extend({throttle: 1000}) для вашего observableArray. Если вы можете создать jsfiddle, это будет намного проще решить. - person Vyacheslav Voronchuk; 17.11.2012
comment
Ок попробую так сделать. Извините за задержку с ответом вам. - person rball; 19.11.2012