3

ng-show が false と評価されても、ロード中のアイコン (スピナー) が表示されたままになることがあります。

ディレクティブは次のとおりです。

angular.module("app.directives").directive("loadingIcon", function() {
return {
    restrict: "A",
    replace: true,
    link: function (scope, element) {

      scope.showLoader = false;

      scope.$on('event:httpRequestStarted', function () {
        // got the request start notification, show the element
        scope.showLoader = true;
      });

      scope.$on('event:httpRequestsCompleted', function () {
        // got the request completed notification, hide the element
        scope.showLoader = false;

      });
    },
    template: "<div ng-show='showLoader' class='fade-in-out loading-icon spin-fx ng-hide' ng-cloak></div>"
  }
});

スピナーをオンにするかどうかをブロードキャストする httpInterceptor は次のとおりです。

// interceptor to show loading icon
$httpProvider.interceptors.push(['$q','$rootScope', function($q, $rootScope) {
  window.requestCount = 0;

  return {
    request: function(config) {

      window.requestCount += 1;
      console.log('start request', config, window.requestCount)
      $rootScope.$broadcast('event:httpRequestStarted');
      return config || $q.when(config);
    },

    response: function(response) {

      $rootScope.$broadcast('event:httpRequestSuccess', response);
      window.requestCount -= 1;
      console.log('got response', response, window.requestCount)
      if ((window.requestCount) === 0) {
        console.log('stop spinny')
        $rootScope.$broadcast('event:httpRequestsCompleted');
      }
      return response || $q.when(response);
    },

console.log 出力と window.requestCount から、ロジックは正しいです。そして、ほとんどの場合、これは機能します。ただし、場合によっては (おそらく競合状態があるのでしょうか?)、読み込みアイコンはクラスで持続しますng-hide-add ng-animate-active ng-hide-add-activeが、 NOng-hideです。ng-hideng-show が false の場合、クラス を追加する必要があると思いましたか?

競合状態が何であるかについて誰かが光を当てることができますか?

編集:

はい、アプリには ngAnimate モジュールが含まれています。アイコンをロードするためのcssは次のとおりです。

.loading-icon {
  background-image: url("/images/loading-icon.png");
  background-repeat: no-repeat;
  background-position: 0 0;
  width: 40px;
  height: 40px;
  z-index: 100000;
  position: fixed;
  right: 50%;
  top: 50%;
  margin: -20px 0 0 -20px;
}

.spin-fx {
  -moz-animation: spin-fx 2s infinite linear;
  -o-animation: spin-fx 2s infinite linear;
  -webkit-animation: spin-fx 2s infinite linear;
  animation: spin-fx 2s infinite linear;
}

// loading icon
.fade-in-out {
  transition:linear 1s;
}

.fade-in-out.ng-enter {
  opacity:0;
}

.fade-in-out.ng-enter-active {
  opacity:1;
}

.fade-in-out.ng-leave {
  opacity:1;
}

.fade-in-out.ng-leave-active {
  opacity:0;
}

angular 1.2.3 と angular-animate 1.2.3 を使用しています

4

2 に答える 2

2
scope.$on('event:httpRequestStarted', function () {
    scope.showLoader = true;
    scope.$apply(); // Apply changes
});

scope.$on('event:httpRequestsCompleted', function () {
    scope.showLoader = false;
    scope.$apply(); // Apply changes
});

イベント ( $on$broadcast、 など$emit) を使用する場合、AngularJS は変更をチェックしません。$scope.apply()手動で変更を確認します。

于 2014-01-09T02:42:31.447 に答える