Apply loading spinner during ui-router resolve

后端 未结 6 1221
面向向阳花
面向向阳花 2020-12-22 17:34

resolve property of $routeProvider allows to execute some jobs BEFORE corresponding view is rendered.

What if I want to display a spinner

6条回答
  •  爱一瞬间的悲伤
    2020-12-22 17:56

    You can use a directive that listens on $routeChangeStart and for example shows the element when it fires:

    app.directive('showDuringResolve', function($rootScope) {
    
      return {
        link: function(scope, element) {
    
          element.addClass('ng-hide');
    
          var unregister = $rootScope.$on('$routeChangeStart', function() {
            element.removeClass('ng-hide');
          });
    
          scope.$on('$destroy', unregister);
        }
      };
    });
    

    Then you place it on the specific view's loader, for example:

    View 1:

    Loading. Please hold.

    View 2:

    
    

    The problem with this solution (and many other solutions for that matter) is that if you browse to one of the routes from an external site there will be no previous ng-view template loaded, so your page might just be blank during resolve.

    This can be solved by creating a directive that will act as a fallback-loader. It will listen for $routeChangeStart and show a loader only if there is no previous route.

    A basic example:

    app.directive('resolveLoader', function($rootScope, $timeout) {
    
      return {
        restrict: 'E',
        replace: true,
        template: '
    Welcome! Content is loading, please hold.
    ', link: function(scope, element) { $rootScope.$on('$routeChangeStart', function(event, currentRoute, previousRoute) { if (previousRoute) return; $timeout(function() { element.removeClass('ng-hide'); }); }); $rootScope.$on('$routeChangeSuccess', function() { element.addClass('ng-hide'); }); } }; });

    The fallback loader would be placed outside the element with ng-view:

    
      
      

    Demo of it all: http://plnkr.co/edit/7clxvUtuDBKfNmUJdbL3?p=preview

提交回复
热议问题