Подтвердить что ты не робот

Angularjs: Как отображать значок загрузки при использовании "разрешения" в $routeProvider?

Следующий код читает через службу и показывает на веб-странице список объектов "страницы" для определенной "категории страниц" (строка). Используя свойство объекта разрешения в $routeProvider.when(), я могу отложить обновление представления до тех пор, пока новое значение не будет готово.

Два вопроса:

  • При запросе нового списка страниц я хочу показать значок загрузки. Как я могу обнаружить (не хакерским способом) событие, когда начинается чтение с сервера (и значок загрузки)? Я предполагаю, что я мог бы сделать что-то вроде $('. Pages-loading-icon'). Show() в службе, но обнаружил, что слишком слишком зависим от gui, помещенный в службу.

  • Когда новое значение будет готово, я хотел бы, чтобы старый погас, и новый, чтобы исчезнуть. Что такое способ angular? Я попытался сделать это в контроллере с помощью $watch, но это приводит к тому, что новое значение будет отображаться незадолго до запуска fadeout.

Код:

app.js:

$routeProvider.when('/:cat', { templateUrl: 'partials/view.html', controller: RouteCtrl, resolve: RouteCtrl.resolve});

controllers.js:

function RouteCtrl($scope, $routeParams, pages) {
        $scope.params = $routeParams;
        $scope.pages = pages;
    }

RouteCtrl.resolve={
    pages: function($routeParams, Pages){
        if($routeParams.hasOwnProperty('cat')){
            return Pages.query($routeParams.cat);
        }
    }
}

services.js: Последние прочитанные страницы хранятся в currentPages и его категории в lastCat.

factory('Pages', function($resource, $q, $timeout){
    return {
        res: $resource('jsonService/cat=:cat', {}, {
            query: {method:'GET', params:{cat:'cat'}, isArray:true}
        }),
        lastCat: null,
        currentPages: null,
        query: function(cat) {
            var res = this.res;
            if(cat != this.lastCat){
                var deferred = $q.defer();
                var p = res.query({'cat':cat}, function(){
                    deferred.resolve(p);
                });
                this.lastCat = cat;
                this.currentPages = deferred.promise;
            }
            return this.currentPages;
        }
    };
})

view.html

<ul >
    <li ng-repeat="page in pages">
        <a href="#{{params.cat}}/{{page.slug}}">{{page.title}}</a>
    </li>
</ul>
4b9b3361

Ответ 1

Не совсем уверен, будет ли это работать в вашем коде, поскольку у вас есть интеграция ресурсов. Но, возможно, стоит посмотреть на события angular: $routeChangeStart и $routeChangeSuccess.

в html:

<span ng-show="isViewLoading"> loading the view... </span>

в контроллере (который определяет область действия html выше):

$scope.isViewLoading = false;
$scope.$on('$routeChangeStart', function() {
  $scope.isViewLoading = true;
});
$scope.$on('$routeChangeSuccess', function() {
  $scope.isViewLoading = false;
});
$scope.$on('$routeChangeError', function() {
  $scope.isViewLoading = false;
});

Ответ 2

Система маршрутизации для angular кажется немного ограниченной..

Это решило это для меня:
http://www.bennadel.com/blog/2420-Mapping-AngularJS-Routes-Onto-URL-Parameters-And-Client-Side-Events.htm

Кроме того, о событиях, запускаемых дважды: если вы настроили маршрут, перейдите к "a/b/c" angular, автоматически настройте другой маршрут, "a/b/c/" (с завершающей косой чертой) для перенаправления к первому (и наоборот), и к двум событиям запуска. Я просто проверяю наличие параметров маршрута.

Относительно ограниченного состояния системы маршрутизации: this pull от angular, чтобы расширить возможности.

Ответ 3

Мне нравится 'ng-show'... Но 'ui-if' проекта пользовательского интерфейса Angular лучше IMHO.. Так как удалите HTML-код из DOM...

<span ui-if = "isViewLoading"> loading the view... </span>

_e

Ответ 4

Вы также можете использовать директиву ng-show. Просто проверьте, пуста ли модель, и отобразите подмножество DOM следующим образом:

    <!-- model not ready -->
    <div style="width: 200" ng-show="lines == ''">
      <div class="progress progress-striped active">
         <div class="bar" style="width: 0%;"></div>
      </div>
    </div>

    <!-- your model code -->
    <ul class="nav nav-tabs nav-stacked">
      <li ng-repeat="line in lines">
        {{line.Id}}
      </li>
    </ul>

Ответ 5

Вы хотите использовать $rootScope, потому что контроль контроллера $scope ограничивается контроллером, и, как это происходит, вы переключаетесь с одного вида (один контроллер) на другой вид (другой контроллер). Таким образом, имеет смысл иметь один-кодовое соответствие.

$rootScope.$on('$stateChangeStart', 
function(event, toState, toParams, fromState, fromParams){ ... })

В этой функции установите $rootScope.isLoadingState, который отобразит ваш индикатор загрузки.

Затем используйте

$rootScope.$on('$stateChangeSuccess', 
function(event, toState, toParams, fromState, fromParams){ ... })

Чтобы отключить эту переменную.

Заполните ссылку здесь

Ответ 6

Вы можете создать директиву, которая будет отображаться на основе широковещательной передачи, которую вы отправляете до и после вызова службы, которую вы можете наложить на $rootScope. Поэтому, если вы вызываете factory, чтобы обрабатывать общие вызовы POST/GET, а прямо перед вызовом вы можете вызвать функцию на $rootScope, например "$ rootScope.startLoading()", и когда он заканчивает вызов "$ rootScope.doneLoading()", где каждый из этих методов транслирует событие, чтобы вы могли выбрать свою директиву. Затем вы просто обрабатываете свою директиву, чтобы поймать события: "scope. $On" ( "startLoading", func (... ", и пусть он вставляет/показывает загрузочный div-шаблон в DOM и запускается, а затем также имеет catch для сделать загрузку, чтобы удалить/скрыть ее.

Таким образом, вы можете иметь хороший общий накладной загрузки.