2015-01-08 15 views
9

Mam spinner to jest pokazane ng-show="loading>0"Czy ng-show być stosowany z opóźnieniem

Czy istnieje sposób mogę wyświetlić ten spinner z opóźnieniem (powiedzmy 1 sekundę)?

Nie mogę użyć limitu czasu, ponieważ przy wielu żądaniach licznik ładowania zostanie zsynchronizowany.

Co potrzebne jest opóźnienie na ng-show poprzez przejście css lub podobny

+0

Czy już zapoznałeś się z dokumentami? [link] (https://docs.angularjs.org/api/ng/directive/ngShow) Przewiń do dołu, a zobaczysz przykład z przejściem i ng-show – graphefruit

+0

Co naprawdę chcesz osiągnąć? Chcesz mieć opóźnienie, aby dla szybkich operacji nie tylko * migało * i wyłączało się, ale przy dłuższych operacjach pojawi się? Tylko wskaźnik ładowania ogólnego przeznaczenia? – Josh

Odpowiedz

4

Oto prostsze podejście, że pracował dla moich potrzeb. W zależności od tego, co robisz, musisz powiązać z tym elementem funkcję setDelay(). Na przykład w moim przypadku przywiązałem setDelay() do wejścia wyboru.

wyzwalania HTML:

<select class="first-option" 
    ng-change="setDelay()" 
    ng-options="o.label for o in download.options" 
    ng-model="optionModel" required> 
</select> 

W kontrolerze, dodać prostą funkcję setDelay która zmieni flagę $scope.delay:

$scope.setDelay = function(){ 
    $scope.delay = true; 
    $timeout(function(){ 
     $scope.delay = false; 
    }, 200); 
}; 

Następnie można po prostu użyć $scope.delay jako flaga w ng- pokaż:

<div class="loading-div" ng-show="delay"> 
    <img src="loading_spinner.gif"> 
</div> 

Pokaż treść af ter zrobić ładowania:

<div ng-show="!delay"> 
    Content is loaded. 
</div> 

Teraz za każdym razem, gdy użytkownik wybierze nową wartość w rozwijanym menu, będzie wyzwalać $scope.delay być ustawiony na true powodując tarczy, aby pokazać, a gdy osiągnie 200, to będzie ustaw na false, powodując, że pokrętło się ukryje.

7

Podejrzewam, że szukasz kołpak ogólnego przeznaczenia, który obejmuje opóźnienie. Standard, pokaż po 200ms lub coś w tym stylu.

Jest to idealny kandydat do dyrektywy, a właściwie całkiem łatwy do wykonania.

Wiem, że jest to długi przykład kodu, ale podstawowym elementem jest dyrektywa. To całkiem proste.

Odsłuchaj kilka zmiennych zakresu i pokazuje po pewnym konfigurowalnym opóźnieniu. Jeśli operacja potrwa dłużej niż opóźnienie, po prostu zostanie anulowana i nigdy się nie pojawi.

(function() { 
 
    'use strict'; 
 

 
    function SpinnerDirective($timeout) { 
 
    return { 
 
     restrict: 'E', 
 
     template: '<i class="fa fa-cog fa-spin"></i>', 
 
     scope: { 
 
     show: '=', 
 
     delay: '@' 
 
     }, 
 
     link: function(scope, elem, attrs) { 
 
     var showTimer; 
 

 
     //This is where all the magic happens! 
 
     // Whenever the scope variable updates we simply 
 
     // show if it evaluates to 'true' and hide if 'false' 
 
     scope.$watch('show', function(newVal){ 
 
      newVal ? showSpinner() : hideSpinner(); 
 
     }); 
 
     
 
     function showSpinner() { 
 
      //If showing is already in progress just wait 
 
      if (showTimer) return; 
 

 
      //Set up a timeout based on our configured delay to show 
 
      // the element (our spinner) 
 
      showTimer = $timeout(showElement.bind(this, true), getDelay()); 
 
     } 
 

 
     function hideSpinner() { 
 
      //This is important. If the timer is in progress 
 
      // we need to cancel it to ensure everything stays 
 
      // in sync. 
 
      if (showTimer) { 
 
      $timeout.cancel(showTimer); 
 
      } 
 

 
      showTimer = null; 
 

 
      showElement(false); 
 
     } 
 

 
     function showElement(show) { 
 
      show ? elem.css({display:''}) : elem.css({display:'none'}); 
 
     } 
 

 
     function getDelay() { 
 
      var delay = parseInt(scope.delay); 
 

 
      return angular.isNumber(delay) ? delay : 200; 
 
     } 
 
     } 
 
    }; 
 
    } 
 

 
    function FakeService($timeout) { 
 
    var svc = this, 
 
     numCalls = 0; 
 

 
    svc.fakeCall = function(delay) { 
 
     numCalls += 1; 
 

 
     return $timeout(function() { 
 

 
     return { 
 
      callNumber: numCalls 
 
     }; 
 

 
     }, delay || 50); 
 
    }; 
 
    } 
 

 
    function MainCtrl(fakeService) { 
 
    var vm = this; 
 

 
    vm.makeCall = function(delay) { 
 
     vm.isBusy = true; 
 
     fakeService.fakeCall(delay) 
 
     .then(function(result) { 
 
      vm.result = result; 
 
     }).finally(function() { 
 
      vm.isBusy = false; 
 
     }); 
 
    } 
 
    } 
 

 
    angular.module('spinner', []) 
 
    .service('fakeService', FakeService) 
 
    .controller('mainCtrl', MainCtrl) 
 
    .directive('spinner', SpinnerDirective); 
 

 
}());
<link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet" /> 
 
<link href="//maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css" rel="stylesheet"> 
 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.8/angular.min.js"></script> 
 

 
<div class="container" ng-app="spinner"> 
 
    <div class="row" ng-controller="mainCtrl as ctrl"> 
 
    <div class="col-sm-12"> 
 
     <h2>{{ctrl.result | json}} 
 
     <spinner show="ctrl.isBusy" delay="200"></spinner> 
 
     </h2> 
 
     <button type="button" 
 
       class="btn btn-primary" 
 
       ng-click="ctrl.makeCall(2000)" 
 
       ng-disabled="ctrl.isBusy">Slow Call 
 
     </button> 
 
     <button type="button" 
 
       class="btn btn-default" 
 
       ng-click="ctrl.makeCall()" 
 
       ng-disabled="ctrl.isBusy">Fast Call 
 
     </button> 
 
    </div> 
 
    </div> 
 
</div>

+1

Doskonałe rozwiązanie! – jdnichollsc

1

Myślę, że czyste rozwiązanie CSS to najlepszy sposób na zrobienie tego.

Oto plunker pokazujący, jak to zrobić. Używanie klas ng-animate do przejścia i stosowanie opóźnienia przejścia z przejściem 10ms (przejście 0s nie działa z css).

odpowiedniej części kodu:

.your-element-class.ng-hide { 
    opacity: 0; 
} 

.your-element-class.ng-hide-add, 
.your-element-class.ng-hide-remove { 
    transition: all linear 0.01s 1s; 
} 

Jedynym powodem, aby użyć dyrektywy niestandardową byłoby używając tych ton razy w kodzie wartości z różnymi opóźnieniami. Własna dyrektywa pozwala na większą elastyczność z czasem opóźnienia.

Powiązane problemy