2013-04-23 3 views
21

Как мне настроить AngularJS, пока загрузка данных не закончится?AngularJS: показывать загрузку HTML до тех пор, пока данные не будут загружены

Если мой контроллер $scope.items = [{name: "One"}] настроить статический, и загрузчик AJAX, который населяет $scope.items[0]['lateLoader'] = "Hello", я хотел бы вертушку, чтобы показать, пока нагрузка AJAX не будет завершена, а затем заполнить связанный промежуток с полученными данными.

<ul ng-repeat="item in items"> 
    <li> 
    <p>Always present: {{item.name}}</p> 
    <p>Loads later: <span ng-bind="item.lateLoader"><i class="icon icon-refresh icon-spin"></i></span></p> 
    </li> 
</ul> 

Этот код заполнит связанный интервал немедленно, и, как item.lateLoader пуст вертушка ничем не заменяется.

Как я должен делать это чисто?

+0

Почему бы не поставить изображение загрузчика статически в разметку? – vittore

ответ

23

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

  1. Использование SetTimeout для имитации вызова Ajax
  2. Значок загрузки предварительно загружен и скрыт при загрузке данных. Просто простая директива ng-hide.
  3. В моем примере нет загружаемого изображения, который будет скрыт (очевидно, ваш html будет иметь правильные ссылки css).

Демо: http://plnkr.co/edit/4XZJqnIpie0ucMNN6egy?p=preview

Вид:

<ul > 
    <li ng-repeat="item in items"> 
    <p>Always present: {{item.name}}</p> 
    <p>Loads later: {{item.lateLoader}} <i ng-hide="item.lateLoader" class="icon icon-refresh icon-spin">loading image i don't have</i></p> 
    </li> 
</ul> 

Контроллер:

app.controller('MainCtrl', function($scope) { 
    $scope.name = 'World'; 
    $scope.items = [{name: "One"}]; 
    setTimeout(function() { 
    $scope.$apply(function() { 
    $scope.items[0].lateLoader = 'i just loaded'; 
    }); 
    }, 1000); 
}); 
5

Я бы создал пользовательскую директиву и поместил разметку по умолчанию с помощью счетчика.

Вот некоторые ссылки на пользовательские директивы

1) Умник видео являются удивительными! http://www.egghead.io/video/xoIHkM4KpHM

2) Официальные Угловые документы по директивам http://docs.angularjs.org/guide/directive

3) Хороший обзор угловых в 60ish минут http://weblogs.asp.net/dwahlin/archive/2013/04/12/video-tutorial-angularjs-fundamentals-in-60-ish-minutes.aspx

+1

Я согласен с этим, хотя он также может просто сделать «ng-show» или «ng-hide» на основе данных, есть или нет (какое-то условие) – lucuma

+0

@ lucuma Да, но кажется, что это хорошая многоразовая вещь для жизни в нем есть собственная директива. – vittore

+0

Я довольно новичок в Angular - если у вас есть пример или ссылка на документацию, которая была бы действительно полезной, хотя я был бы рад пойти на охотничью документацию самостоятельно! –

0

@lucuma,

Великий ответ, альтернативой может быть впрыснуть $ тайм-аут и заменить встроенную функцию тайм-аута n:

var app = angular.module('plunker', []); 

app.controller('MainCtrl', function($scope, $timeout) { 

     $scope.name = 'World'; 
     $scope.items = [{name: "One"}]; 
     $timeout(function() { 
       $scope.$apply(function() { 
         $scope.items[0].lateLoader = 'i just loaded'; 
       }); 
     }, 1000); 
}); 
+0

. SetTimeout просто использовался для имитации ожидания, хотя вы правы, было бы лучше использовать $ timeout. – lucuma

+4

$ timeout полезен, потому что он автоматически включает обратный вызов в $. То есть вы можете удалить '$ scope. $ apply (function() {' из вашего примера. –

19

Я действительно использовал решение для этого какое-то время, которое отлично работает и лучше, чем использование таймаута по моему мнению. Я использую $ resource, но вы можете сделать то же самое с $ http. В моих ресурсных объектах я добавляю бит в следующий код, который устанавливает значение true.

$scope.customer = $resource(dataUrl + "/Course/Social/" + courseName) 
    .get({}, function (data) { data.loaded = true; }); 

Тогда, на мой взгляд, я могу использовать:

ng-hide="customer.loaded" 

Конечно, я не хотел бы использовать $ ресурс непосредственно в контроллере, я извлекаю что к службе customerRepository, но это было более просто показать это здесь.

+1

Это, безусловно, лучшее решение. – Steven

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

  • Нет связанных вопросов^_^