2015-01-08 8 views
9

Ho un filatore questo è mostrato con ng-show="loading>0"Può NG-spettacolo direttiva essere utilizzato con un ritardo

Esiste un modo per visualizzare questo filatore con un ritardo (diciamo 1 secondo)?

Non riesco a utilizzare un timeout perché con più richieste di caricamento del contatore non sarà più sincronizzato.

cosa ho bisogno è un ritardo sul ng-show via di transizione css o simili

+0

Hai già esaminato i documenti? [link] (https://docs.angularjs.org/api/ng/directive/ngShow) Scorri verso il basso e vedrai un esempio con transizione e ng-show – graphefruit

+0

Cosa stai cercando di ottenere qui? Si desidera avere un ritardo in modo che per operazioni veloci non solo * lampeggi * e si spenga, ma per operazioni più lunghe viene visualizzato? Solo un indicatore di caricamento generico? – Josh

risposta

4

Ecco un approccio più semplice che ha lavorato per le mie esigenze. A seconda di quale sia la tua azione, legherei la funzione setDelay() all'elemento. Ad esempio, nel mio caso ho legato setDelay() a un input selezionato.

trigger HTML:

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

nel controller, aggiungere una semplice funzione setDelay che cambierà la bandiera $scope.delay:

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

Poi, si può semplicemente utilizzare $scope.delay come una bandiera in ng- mostra:

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

E mostra il contenuto af ter carico fatto:

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

Ora, ogni volta che l'utente seleziona un nuovo valore nel menu a tendina, si innescherà $scope.delay da impostare per true causando il filatore di mostrare, e quando raggiunge 200, sarà impostato su false causando la chiusura dello spinner.

7

mio sospetto è che siete alla ricerca di un filatore di uso generale che comprende un ritardo. Lo standard, mostra dopo 200ms o qualcosa del genere.

Questo è un candidato perfetto per una direttiva, e in realtà piuttosto facile da realizzare.

So che questo è un lungo esempio di codice, ma il pezzo principale è la direttiva. È piuttosto semplice

Ascoltare alcune variabili di ambito e visualizza dopo un ritardo configurabile. Se l'operazione richiede più tempo del ritardo, verrà annullata e non verrà mai visualizzata.

(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

Ottima soluzione! – jdnichollsc

1

Penso che una soluzione CSS pura sia il modo migliore per farlo.

Ecco un plunker che mostra come farlo. Utilizzare le classi animate da ng per la transizione e applicare un ritardo di transizione con una transizione di 10 ms (la transizione 0s non funziona con css).

parte rilevante del codice:

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

L'unica ragione per usare una direttiva personalizzato per esso sarebbe utilizzando questo tonnellate di volte nel codice con il valore di diversi ritardi. Una direttiva personalizzata consente una maggiore flessibilità con i tempi di ritardo.

Problemi correlati