2014-10-30 2 views
1

Мне нужно отобразить gif загрузки, в то время как фоновая задача (с использованием обещаний JQuery выполняется). У меня есть большая часть кода, но моя проблема заключается в следующем:Knockout.js: Как отображать загружаемое изображение при завершении асинхронного вызова

Задача: загрузочный экран отображается, когда данные готовы к отображению, что приводит к потере цели использования gif загрузки! Как отобразить gif прямо в начале и затем удалить его после того, как данные будут готовы для отображения.

Я использую специальный обработчик привязки KO с наблюдаемым флагом.

Вы можете увидеть код в этом jsfiddle

JavaScript:

ko.bindingHandlers.loadingList = { 

    init: function (element, valueAccessor) { 
     ko.utils.unwrapObservable(valueAccessor()); 
     if (valueAccessor() == true) { 
      $(element).wrap($('<div>', { 
       "class": "loading" 
      })); 
      $(element).before($('<div>', { 
       "class": "loading_inner" 
      })); 
     } else { 
      $(element).parent().replaceWith($(element)); 
     } 
    }, 
    update: function (element, valueAccessor, allBindingsAccessor) { 
     ko.utils.unwrapObservable(valueAccessor()); 
     if (valueAccessor() == true) { 
      $(element).wrap($('<div>', { 
       "class": "loading" 
      })); 
      $(element).before($('<div>', { 
       "class": "loading_inner" 
      })); 
     } else { 
      $(element).parent().replaceWith($(element)); 
     } 
    } 
}; 


function PersonViewModel(callback) { 
    var self = this; 

    self.InProgress = ko.observable(true); 
    self.persons = ko.observableArray([]); 

    // Get available audits 

    var promises = []; 
    promises.push(GetPersons()); 

    $.when.apply($, promises).then(function() { 
     self.persons(arguments[0]); 
     self.InProgress(false); 
    }); 
} 

ko.applyBindings(new PersonViewModel()); 

function GetPersons() { 

    var dfrd = $.Deferred(); 

    var result = [{ 
     Name: 'John Smith', 
     Country: 'USA' 
    }, { 
     Name: 'Juan Carlos', 
     Country: 'Spain' 
    }]; 

    setTimeout(function() { 
     dfrd.resolve(result) 
    }, 3000); 

    return dfrd; 
} 

HTML:

<div class="container"> 
    <h1>Persons</h1> 

    <hr /> 
    <table data-bind="foreach: persons, loadingList:InProgress()"> 
     <thead> 
      <tr> 
       <th><span>Name</span> 

       </th> 
       <th><span>Country</span> 

       </th> 
      </tr> 
     </thead> 
     <tbody> 
      <tr> 
       <td><span data-bind="text:Name"></span> 

       </td> 
       <td><span data-bind="text:Country"></span> 

       </td> 
      </tr> 
      <td> 
    </table> 
</div> 

ответ

1

Я просто отредактировал код обновления с этим

setTimeout(function(){$(element).parent().parent().replaceWith($(element));}, 1000); 

оговоренных была просто проверить, была ли загрузка появляться http://jsfiddle.net/zL8vtwsa/30/

В соответствии с вашими комментариями, я попробовал его вокруг с контейнером, менее обязательным для показа, и я думаю, что это послужит цели

http://jsfiddle.net/zL8vtwsa/78/

<tbody> 
      <!-- ko foreach:persons --> 
      <!-- /ko --> 
    </tbody> 
+0

Спасибо, Рохит Наир за вашу помощь. Я даю вам предварительный голос. Как показать загрузку gif в начале? Как я упоминал в своем посте, gif отображается так же, как и данные, готовые для отображения. – user1309226

+0

@ user1309226 Я обновил ответ –

+0

Работает отлично! – user1309226

2

код в методе обновления заменяет родительский DIV (. загрузка), но не удаляет элемент перед ним (.loading-inner) , который, кстати, вставлен за пределы .loading div.

else { 
    $(element).parent().replaceWith($(element)); 
} 

Так что, казалось бы, погрузка кок просто добавляется в том месте, я установил его с помощью .prepend, а затем .before, увидеть его в действии здесь: http://jsfiddle.net/2x6wx6wa/2/

некоторые другие биты. функция GetPersons должна возвращать return dfrd.promise(), чтобы сделать ее неизменной, Create/Update применяются, когда этот код запускается первым, проверьте свой метод обновления, если добавочный счетчик загрузки уже добавлен.

Edit:

Загрузочный кок не показан на старте из-за следующего CSS, при удалении его прекрасно работает:

.loading { 
    display: table; 
    position: relative; 
} 

Вместо использования PREPEND/до, я мы добавили чек, чтобы обеспечить загрузку div только один раз, который оказался «реальной» основной проблемой при ближайшем рассмотрении. Смотрите изменения здесь: http://jsfiddle.net/tkvvjutx/

+0

Спасибо Dead.Rabit. Я проверил ваш код и две вещи: во-первых, загрузка gif не отображается в начале, а только отображается с данными.Во-вторых, gif не удаляется после замены данных. – user1309226

Смежные вопросы