programing

UI 라우터 확인 중 로드 스피너 적용

newnotes 2023. 3. 1. 11:27
반응형

UI 라우터 확인 중 로드 스피너 적용

resolve의 특성$routeProvider를 사용하면 해당 보기가 렌더링되기 전에 일부 작업을 실행할 수 있습니다.

작업 실행 중에 스피너를 표시하여 사용자 경험을 향상시키려면 어떻게 해야 합니까?
실제로 그렇지 않으면 예를 들어 600초 이상 뷰 요소가 표시되지 않아 응용 프로그램이 차단되었다고 느낄 수 있습니다.

물론, 글로벌하게 정의할 수 있는 방법이 있었습니다.div현재 뷰에서 벗어나 스피너를 표시하기 위해 표시할 요소는 다음과 같습니다.$scope.$rootChangeStart기능.
하지만 중간에 서투른 스피너로 페이지 전체를 숨기고 싶지는 않아요.
로딩이 표시되는 방식에 대해 제 웹 앱의 몇 페이지가 달라졌으면 합니다.

위에서 설명한 정확한 문제가 포함된 흥미로운 게시물을 발견했습니다.

이 접근 방식은 UI 환경을 끔찍하게 만듭니다.사용자가 버튼을 클릭하여 목록을 새로 고치면 라이브러리에서는 상태 변경의 영향을 받는 보기에만 스피너를 표시할 수 없기 때문에 전체 화면이 일반적인 스피너로 표시됩니다.사양하겠습니다.

어쨌든, 이 문제를 제기하고 나서, 「해결」기능이 안티 패턴이라는 것을 깨달았습니다.모든 약속이 해결되기를 기다린 후 상태 변화를 활성화합니다.이는 완전히 잘못된 것입니다. 즉, 상태 간 전환 애니메이션이 데이터 로드와 병렬로 실행되어 데이터 로드가 상태 간 전환 애니메이션을 덮을 수 있도록 해야 합니다.

예를 들어 항목 목록이 있다고 가정하고 항목 중 하나를 클릭하면 목록이 숨겨지고 항목의 세부 정보가 다른 보기에 표시됩니다.평균적으로 400ms가 걸리는 아이템 상세에 대해 비동기 로드가 있는 경우, 대부분의 경우 아이템 상세 뷰에 300ms의 "leave" 애니메이션을 표시하고 아이템 상세 뷰에 300ms의 "Enter" 애니메이션을 표시함으로써 로드를 거의 완전히 커버할 수 있습니다.이렇게 하면 UI에 더욱 매끄러운 느낌을 줄 수 있으며 대부분의 경우 스피너가 표시되지 않습니다.

단, 이를 위해서는 비동기 로드와 상태 변경 애니메이션을 동시에 시작해야 합니다.해결 방법을 사용하면 전체 비동기 애니메이션이 애니메이션이 시작되기 전에 발생합니다.사용자는 클릭해서 스피너를 보고 전환 애니메이션을 볼 수 있습니다.전체 상태 변경에는 1000ms까지 소요되며, 이는 너무 느립니다.

"해결"은 약속을 기다리지 않는 옵션이 있는 경우 서로 다른 뷰 간에 종속성을 캐시하는 유용한 방법이 될 수 있지만, 상태 변경이 시작되기 전에 항상 해결한다는 현재의 동작으로 인해 IMO는 거의 무용지물입니다. 비동기 부하를 수반하는 종속성에는 사용하지 마십시오.

요?resolve데이터를 로딩하고 해당 컨트롤러에 직접 로딩할 수 있습니까?따라서 작업이 실행되는 동안 전역이 아닌 보기에서 원하는 위치에서 해당 보기를 업데이트할 수 있습니다.

''라는할 수 .$routeChangeStart, 를 들면 기동시의 .

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);
    }
  };
});

그런 다음 다음과 같이 특정 보기의 로더에 배치합니다.

표시 1:

<div show-during-resolve class="alert alert-info">
  <strong>Loading.</strong>
  Please hold.
</div>

표시 2:

<span show-during-resolve class="glyphicon glyphicon-refresh"></span>

이 솔루션(및 그 외의 많은 솔루션)의 문제는 외부 사이트에서 루트 중 하나를 참조할 경우 이전 ng-view템플릿이 로드되지 않기 때문에 해결 중에 페이지가 공백일 수 있다는 것입니다.

이 문제는 폴백로더로서 기능하는 디렉티브를 작성함으로써 해결할 수 있습니다. ''를 듣습니다.$routeChangeStart및 이전 경로가 없는 경우에만 로더를 표시합니다.

기본적인 예:

app.directive('resolveLoader', function($rootScope, $timeout) {

  return {
    restrict: 'E',
    replace: true,
    template: '<div class="alert alert-success ng-hide"><strong>Welcome!</strong> Content is loading, please hold.</div>',
    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');
      });
    }
  };
});

폴백 로더는 ng-view를 사용하여 요소 외부에 배치됩니다.

<body>
  <resolve-loader></resolve-loader>
  <div ng-view class="fadein"></div>
</body>

모든 것의 데모: http://plnkr.co/edit/7clxvUtuDBKfNmUJdbL3?p=preview

나는 이것이 꽤 깔끔하다고 생각한다.

app.run(['$rootScope', '$state',function($rootScope, $state){

  $rootScope.$on('$stateChangeStart',function(){
      $rootScope.stateIsLoading = true;
 });


  $rootScope.$on('$stateChangeSuccess',function(){
      $rootScope.stateIsLoading = false;
 });

}]);

그 후 표시된다.

<div ng-show='stateIsLoading'>
  <strong>Loading.</strong>
</div>

Pranay의 대답을 더 하자면, 나는 이렇게 했다.

JS:

app.run(['$rootScope',function($rootScope){

    $rootScope.stateIsLoading = false;
    $rootScope.$on('$routeChangeStart', function() {
        $rootScope.stateIsLoading = true;
    });
    $rootScope.$on('$routeChangeSuccess', function() {
        $rootScope.stateIsLoading = false;
    });
    $rootScope.$on('$routeChangeError', function() {
        //catch error
    });

}]);

HTML

<section ng-if="!stateIsLoading" ng-view></section>
<section ng-if="stateIsLoading">Loading...</section>

2년 늦었습니다.그렇습니다.이러한 솔루션들은 효과가 있습니다만, 이러한 모든 것을 간단하게 실행 블록으로 처리할 수 있습니다.

.run(['$rootScope','$ionicLoading', function ($rootScope,$ionicLoading){


  $rootScope.$on('loading:show', function () {
    $ionicLoading.show({
        template:'Please wait..'
    })
  });

  $rootScope.$on('loading:hide', function () {
    $ionicLoading.hide();
  });

  $rootScope.$on('$stateChangeStart', function () {
    console.log('please wait...');
    $rootScope.$broadcast('loading:show');
  });

  $rootScope.$on('$stateChangeSuccess', function () {
    console.log('done');
    $rootScope.$broadcast('loading:hide');
  });

}])

다른 건 필요 없어요꽤 쉬운데?여기 그것이 실제로 행해지고 있는 예가 있습니다.

in ui-router 1.0 $state변경* 이벤트는 권장되지 않습니다.대신 전환 후크를 사용하십시오.상세한 것에 대하여는, 이하의 이행 가이드를 참조해 주세요.

https://ui-router.github.io/guide/ng1/migrate-to-1_0#state-change-events

$state의 문제Change Start' 및 '$state'ChangeSuccess'는 마지막 상태로 돌아가도 "$rootScope.stateIsLoading"이 새로 고쳐지지 않습니다.그것에 대한 해결책이 있나요?또, 다음과 같은 것도 사용했습니다.

    $rootScope.$on('$viewContentLoading',
        function(event){....});

그리고.

    $rootScope.$on('$viewContentLoaded',
        function(event){....});

하지만 같은 문제가 있습니다.

언급URL : https://stackoverflow.com/questions/24200909/apply-loading-spinner-during-ui-router-resolve

반응형