2015-01-08 6 views
9

で使うことができますか?ことができますngのショーディレクティブは、私は遅延(例えば1秒)で、このスピナーを表示することができます方法はあります私は、これは<code>ng-show="loading>0"</code></p> <p>で示されているスピナーを持って遅延

複数のリクエストでローディングカウンタが同期しなくなるため、タイムアウトを使用できません。私は必要なもの

は私の疑いはあなたが遅延を含む一般的な目的のスピナーを探しているということであるCSSトランジションまたは類似

+0

あなたは既にドキュメントを調べましたか? [link](https://docs.angularjs.org/api/ng/directive/ngShow) 下にスクロールすると、トランジションとng-showのサンプルが表示されます – graphefruit

+0

ここで本当に目的を達成しようとしていますか?あなたは速い操作のために*点滅するだけではオン/オフするのではなく、より長い操作のためにそれが現れるように遅れを持ちたいですか?単なる汎用目的のロードインジケータですか? – Josh

答えて

4

ここに私のニーズのために働いていた単純なアプローチです。あなたの行動に応じて、関数setDelay()を要素に結びつけます。たとえば、私の場合、私はsetDelay()を選択入力に結びつけました。

トリガーHTML:あなたは、単にng-でフラグとして$scope.delayを使用することができ、その後

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

あなたのコントローラで
<select class="first-option" 
    ng-change="setDelay()" 
    ng-options="o.label for o in download.options" 
    ng-model="optionModel" required> 
</select> 

、フラグ$scope.delayを変更する単純な機能setDelayを追加表示:

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

と表示内容af TER行わロード:今すぐ

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

、ユーザーがドロップダウンメニューに新しい値を選択するたびに、それは$scope.delayをトリガするには、表示するスピナーを引き起こしtrueに設定すると、それが200に到達したとき、それは次のようになりますfalseに設定すると、スピナーが非表示になります。

7

経由ng-show上の遅延です。標準は、200msまたはそのようなものの後に表示されます。

これは指示文の完璧な候補であり、実際には非常に簡単です。

これは長いコード例ですが、主要な部分は指令です。それはかなり簡単です。

いくつかのスコープ変数を聞いて、設定可能な遅延の後に表示します。操作が遅延よりも時間がかかる場合は、キャンセルされ、決して表示されません。

(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

優れたソリューション! – jdnichollsc

1

私は、純粋なCSSソリューションがこれを行う最良の方法だと思います。

ここには、方法を示すplunkerがあります。トランジションにng-animateクラスを使用し、10msのトランジションでトランジション遅延を適用します(0sトランジションはcssで動作しません)。

コードの関連部分:それは異なる遅延値を使用してコード内で何回このトンを使用したことになるためのカスタムディレクティブを使用する

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

唯一の理由。カスタムディレクティブを使用すると、遅延のタイミングに柔軟性を持たせることができます。

関連する問題