IT

(Angular-ui-router) 해결 프로세스 중 로딩 애니메이션 표시

lottoking 2020. 10. 8. 07:27
반응형

(Angular-ui-router) 해결 프로세스 중 로딩 애니메이션 표시


이것은 두 부분으로 된 질문입니다.

  1. 컨트롤러를로드하기 전에 특정 서버 데이터를 가져 오기 위해 $ stateProvider.state () 내부의 속성을 사용하고 있습니다. 이 과정에서로드 애니메이션을 표시해야합니까?

  2. resolve 속성도 사용하는 마이너스 상태가 있습니다. 문제는 UI 라우터는 모든 로드하기 전에 결의를 받을 수 있습니다. 모든 마이너스가 해결 될 때까지 기다릴 필요없이 해결이 해결 될 때 컨트롤러를로드 할 수있는 방법이 있습니까? 이에 대한 대답은 첫 번째 문제도 있습니다.


편집 : 여기에 더 쉬운 솔루션이 자동으로 잘 테스트되고 작동합니다.

내 메인 포함에는 포함

$scope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
    if (toState.resolve) {
        $scope.showSpinner();
    }
});
$scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
    if (toState.resolve) {
        $scope.hideSpinner();
    }
});

이 상태 변경이 완료 될 때가있는 상태로 이동하려고 할 때마다 스피너를 표시하고 숨 깁니다. (즉,로드되는 경우 스피너도 표시)이 솔루션은 저에게 잘 작동합니다.

다음은 참조 및 대안으로 나의 제안 제안입니다.

  1. 애플리케이션 컨트롤러에서 stateChangeStart이벤트를 수신 하고 해결 중에 스피너를 표시하려는 상태로 전환 하려는지 확인합니다 ( https://github.com/angular-ui/ui-router/wiki/Quick 참조). -참조 # wiki-events-1 )

    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
        if (toState.name == 'state.with.resolve') {
            $scope.showSpinner();  //this is a function you created to show the loading animation
        }
    })
    
  2. 컨트롤러가 마침내 호출되면 스피너를 숨길 수 있습니다.

    .controller('StateWithResolveCtrl', function($scope) {
        $scope.hideSpinner();
    })
    

또한 $stateChangeError이벤트 를 수신 하고 오류를 처리하는 동안 애니메이션을 숨기면 해결 보관 수있는 오류를 확인할 수도 있습니다 .

컨트롤러간에 스피너에 대한 논리를 배포 할 때 완전히 처분 방법입니다. 도움이되기를 바랍니다.


나는 나를 위해 완벽하게 작동하는 다음 솔루션을 개발했습니다.

1. 다음 app.run을 추가합니다.

app.run(function($rootScope){

    $rootScope
        .$on('$stateChangeStart', 
            function(event, toState, toParams, fromState, fromParams){ 
                $("#ui-view").html("");
                $(".page-loading").removeClass("hidden");
        });

    $rootScope
        .$on('$stateChangeSuccess',
            function(event, toState, toParams, fromState, fromParams){ 
                $(".page-loading").addClass("hidden");
        });

});

2. 로딩 표시기 UI 뷰 바로 위에. ui-view div에 id = "ui-view"를 추가합니다.

<div class="page-loading">Loading...</div>
<div ui-view id="ui-view"></div>

3. CSS에 다음을 추가하십시오.

.hidden {
  display: none !important;
  visibility: hidden !important;
}

노트 :

A. 위 코드는 1) 앵귤러 앱이 처음로드 될 때 2) 뷰가 변경 될 때 두 가지 경우에로드 표시기를 표시 합니다.

B. 앵귤러 앱이 처음로드 될 때 (뷰가로드되기 전) 표시기가 표시되지 않고 다음과 같이 추가 로드 div에 숨겨진 클래스를 합니다.

<div class="page-loading hidden">Loading...</div>

angular-loading-bar를 사용하면 네트워크 액세스로 인해 긴 해결에 정말 잘 작동하게 되었습니다 .


속성이 해결되면 ui-router로 채워질 div에 콘텐츠를 추가하는 것은 무엇입니까?

당신의 index.html

<div ui-view class="container">
    Loading....
</div>

이제 사용자는 속성이 해결되는 동안 "로드 중 ..."을 볼 수 있습니다. 모든 것이 준비되면 콘텐츠가 앱 콘텐츠로 ui-router로 대체됩니다.


$http보류중인 요청이 있을 때만 표시되는 애니메이션 GIF를 사용 합니다.

내 기본 페이지 템플릿에는 navbar 및 navbar 컨트롤러가 있습니다. 컨트롤러의 관련 부분은 다음과 가변.

controllers.controller('NavbarCtrl', ['$scope', '$http',
    function ($scope, $http) {
        $scope.hasPendingRequests = function () {
            return $http.pendingRequests.length > 0;
        };
    }]);

내 HTML의 해당 코드는 다음과 가변적입니다.

<span class="navbar-spinner" ng-show="hasPendingRequests()">
    <img src="/static/img/spinner.gif">
</span>

도움이 되셨기를 바랍니다.


내 아이디어는 전이 사이의 상태 그래프에서 경로를 중재 $stateChangeStart한 모든 뷰를 수집하는 것입니다. 그런 다음 모든 ui-view지시문은 해당 뷰가 전환에 관련되어 있는지 감시하고 해당 'ui-resolving'요소에 클래스를 추가합니다 .

plunker의 데모는 두 개의 루트 상태를 소개 first하고 second후자는 두 개의 하위 상태를 가지고 second.sub1second.sub2. 상태 second.sub2는 또한 footer조부모에게보기를 대상으로 합니다.


페이지가 모든 상태 (모든 페이지) 사이를 설치할 때 app.js에 넣을 때 전역 적으로 사용하는 로더입니다.

.run(
    ['$rootScope',
        function($rootScope) {
            $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
                $rootScope.preloader = true;
            })
            $rootScope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) {
                $rootScope.preloader = false;
            })
        }
    ])

HTML에서 :

<div ng-show="preloader">Loading...</div>

주로 코드베이스를 깨끗하게 유지하기 위해 모든 로딩 활동과 일치하는 지시문을 사용하는 것을 선호합니다.

angular.module('$utilityElements', [])
.directive('loader',['$timeout','$rootScope', function($timeout, $rootScope) {
    return {
      restrict: 'A',
      template: '<div id="oneloader" class="hiddenload">loading...</div>',
      replace: true,
      compile: function (scope, element, attrs) {
        $timeout(function(){
          $rootScope
              .$on('$stateChangeStart',
                  function(event, toState, toParams, fromState, fromParams){
                      $("#oneloader").removeClass("hiddenload");
              });

          $rootScope
              .$on('$stateChangeSuccess',
                  function(event, toState, toParams, fromState, fromParams){
                      //add a little delay
                      $timeout(function(){
                        $("#oneloader").addClass("hiddenload");
                      },500)
              });
        }, 0);
      }
    }
  }]);

등의 사용 $stateChangeStart은 이후 더 이상 사용되지 않으며 Transition Hooks 로 대체되었습니다 . 따라서 Stefan Henze의 답변에 대한 업데이트 버전은 다음과 같습니다.

$transitions.onStart({}, function(transition) {
  if (transition.to().resolve) {
    $scope.showSpinner();
  }
});

$transitions.onSuccess({}, function(transition) {
  if (transition.to().resolve) {
    $scope.hideSpinner();
  }
});

부모 컨트롤러에서 이것을 사용할 수 있습니다. 주입하는 것을 잊지 마십시오 $transitions-

.controller('parentController',['$transitions',function($transitions){...}]);

또한 resolve빈 객체 인 a는 여전히 렌더링 transition.to().resolve == true되므로 resolve상태 선언에 빈 자리 표시자를 두지 마십시오 .


라우터에서 resole을 사용하는 동안보기를 사용하는 내 아이디어는 멋지게 작동합니다. 이 시도.

//edit index.html file 
<ion-nav-view>
    <div ng-show="loadder" class="loddingSvg">
        <div class="svgImage"></div>
    </div>
</ion-nav-view>

// css file

.loddingSvg {
    height: 100%;
    background-color: rgba(0, 0, 0, 0.1);
    position: absolute;
    z-index: 99;
    left: 0;
    right: 0;
}

.svgImage {
    background: url(../img/default.svg) no-repeat;
    position: relative;
    z-index: 99;
    height: 65px;
    width: 65px;
    background-size: 56px;
    top: 50%;
    margin: 0 auto;
}

// edit app.js

 .run(function($ionicPush, $rootScope, $ionicPlatform) {




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

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

});

누군가를 사용 중이고 다음보기를로드하기 전에 ngRoute대기하고 ui를 resolve사용 angular-bootstrap-ui하는 경우 다음을 수행 할 수 있습니다 .

app.config([
  "$routeProvider", "$locationProvider", function($routeProvider, $locationProvider) {
    return $routeProvider.when("/seasons/:seasonId", {
      templateUrl: "season-manage.html",
      controller: "SeasonManageController",
      resolve: {
        season: [
          "$route", "$q", "$http", "$modal", function($route, $q, $http, $modal) {
            var modal, promise, seasonId;
            modal = $modal.open({
              backdrop: "static",
              template: "<div>\n  <div class=\"modal-header\">\n    <h3 class=\"modal-title\">\n      Loading...\n    </h3>\n  </div>\n  <div class=\"modal-body\">\n    <progressbar\n      class=\"progress-striped active\"\n      value=\"'100'\">\n    </progressbar>\n  </div>\n</div>",
              keyboard: false,
              size: "lg"
            });
            promise = $q.defer();
            seasonId = $route.current.params.seasonId;
            $http.get("/api/match/seasons/" + seasonId).success(function(data) {
              modal.close();
              promise.resolve(data);
            }).error(function(data) {
              modal.close();
              promise.reject(data);
            });

            return promise.promise;
          }
        ]
      }
    });
  }
]);

참고 URL : https://stackoverflow.com/questions/18961332/angular-ui-router-show-loading-animation-during-resolve-process

반응형