AngularJS में $ http अनुरोध के दौरान स्पिनर GIF दिखाएं?


234

मैं $httpअजाक्स अनुरोध करने के लिए AngularJS की सेवा का उपयोग कर रहा हूं ।

स्पिनर जीआईएफ (या अन्य प्रकार का व्यस्त संकेतक) कैसे दिखाया जा सकता है जबकि अजाक्स अनुरोध निष्पादित कर रहा है?

मुझे ajaxstarteventAngularJS प्रलेखन में ऐसा कुछ नहीं दिखता ।


2
यदि आप HTTP इंटरसेप्टर्स पर आधारित एक साधारण स्पिनर चाहते हैं, तो मेरे पास इसके लिए कोणीय मॉड्यूल है। यह लोकप्रिय आइडेंटिफाइड शाम स्पिनर का उपयोग करता है। देखिए: github.com/harinair/angular-sham-spinner
हरि गंगाधरन

1
मैंने एक प्लगइन कोणीय-वीट्यूटर लिखा है , यह कॉल शूटिंग से ठीक पहले कॉन्फिग डेटा के साथ एक ईवेंट जारी करता है और रेस्पोंस को पुनः प्राप्त करने के ठीक बाद एक और रिलीज़ करता है, आप उन घटनाओं को पकड़ने वाले वैश्विक लोडर लिख सकते हैं
सिद्धार्थ

जवाबों:


88

यहाँ वर्तमान पिछले AngularJS incantations हैं:

angular.module('SharedServices', [])
    .config(function ($httpProvider) {
        $httpProvider.responseInterceptors.push('myHttpInterceptor');
        var spinnerFunction = function (data, headersGetter) {
            // todo start the spinner here
            //alert('start spinner');
            $('#mydiv').show();
            return data;
        };
        $httpProvider.defaults.transformRequest.push(spinnerFunction);
    })
// register the interceptor as a service, intercepts ALL angular ajax http calls
    .factory('myHttpInterceptor', function ($q, $window) {
        return function (promise) {
            return promise.then(function (response) {
                // do something on success
                // todo hide the spinner
                //alert('stop spinner');
                $('#mydiv').hide();
                return response;

            }, function (response) {
                // do something on error
                // todo hide the spinner
                //alert('stop spinner');
                $('#mydiv').hide();
                return $q.reject(response);
            });
        };
    });

//regular angular initialization continued below....
angular.module('myApp', [ 'myApp.directives', 'SharedServices']).
//.......

यहाँ इसका बाकी (HTML / CSS) .... उपयोग किया जा रहा है

$('#mydiv').show(); 
$('#mydiv').hide(); 

इसे टॉगल करें। नोट: ऊपर का उपयोग पोस्ट की शुरुआत में कोणीय मॉड्यूल में किया जाता है

#mydiv {  
    position:absolute;
    top:0;
    left:0;
    width:100%;
    height:100%;
    z-index:1000;
    background-color:grey;
    opacity: .8;
 }

.ajax-loader {
    position: absolute;
    left: 50%;
    top: 50%;
    margin-left: -32px; /* -1 * image width / 2 */
    margin-top: -32px;  /* -1 * image height / 2 */
    display: block;     
}

<div id="mydiv">
    <img src="lib/jQuery/images/ajax-loader.gif" class="ajax-loader"/>
</div>

19
ध्यान दें कि आप angular.element('#mydiv').show()इसके बजाय का उपयोग कर सकते हैं$('#mydiv').show()
JMaylin

8
यदि आपका पृष्ठ कई ajax अनुरोध करता है तो यह काम नहीं करता है। पहले अनुरोधों के समाप्त होने के बाद यह लोडिंग जिफ को छिपा देगा।
मीकर

38
AngularJS की सर्वोत्तम प्रथाओं (जो स्वीकृत समाधान का उल्लंघन है) के अनुसार आपको एक निर्देश के बाहर DOM को संशोधित नहीं करना चाहिए। एक निर्देश के भीतर से तत्वों पर शो को छिपाने / छिपाने पर विचार करें।
Mariusz

7
मुझे यकीन नहीं है कि मैं टिप्पणी करना पर्याप्त जानता हूं ... लेकिन ng-classतत्वों को दिखाने और छिपाने के लिए JQuery का उपयोग करने के बजाय निर्देश का उपयोग करने के बारे में जाने का सही तरीका नहीं होगा ?
जेम्स हेडल

2
@JamesHeald सही है .. आपको कभी भी कोणीय में किसी भी डोम हेरफेर के लिए jQuery का उपयोग करने की आवश्यकता नहीं होनी चाहिए। में देखें: एनजी-क्लास, एनजी-इफ, एनजी-छिपाने, एनजी-शो, आदि .. लगभग हर चीज के लिए एक निर्देश है जो आपको कभी भी आवश्यकता होगी।
14:11 पर jKlaus

471

यह वास्तव में आपके विशिष्ट उपयोग के मामले पर निर्भर करता है, लेकिन एक सरल तरीका इस तरह से एक पैटर्न का पालन करेगा:

.controller('MainCtrl', function ( $scope, myService ) {
  $scope.loading = true;
  myService.get().then( function ( response ) {
    $scope.items = response.data;
  }, function ( response ) {
    // TODO: handle the error somehow
  }).finally(function() {
    // called no matter success or failure
    $scope.loading = false;
  });
});

और फिर अपने टेम्पलेट में इस पर प्रतिक्रिया करें:

<div class="spinner" ng-show="loading"></div>
<div ng-repeat="item in items>{{item.name}}</div>

223
यदि आपके पास एक ही समय में कई ajax अनुरोध हैं, तो आप loadingपूर्णांक के रूप में घोषणा कर सकते हैं $scope.loading = 0;, जब कोई अनुरोध आप करना शुरू करते हैं $scope.loading++;, और जब यह समाप्त होता है तो आप करते हैं $scope.loading--;। और टेम्पलेट में परिवर्तन करने के लिए कुछ भी नहीं है। तो स्पिनर को तब प्रदर्शित किया जाता है जब प्रगति में कम से कम एक अनुरोध होता है, और बाकी समय छिपा
रहता है

16
आपको संभवतः त्रुटि फ़ॉलबैक फ़ंक्शन में भी झूठी लोडिंग सेट करनी चाहिए।
21

3
@sebnukem सही आप हैं। यह एक उच्च स्तरीय उदाहरण था, लेकिन मैंने आगे बढ़कर इसे स्पष्टता के लिए जोड़ा। प्रतिक्रिया के लिए धन्यवाद!
जोश डेविड मिलर

1
@ जेमलिन - आप तब $ गुंजाइश पर $ घड़ी का उपयोग कर सकते हैं। अन्य काम करना लोड करना
जेसन

5
$scope.loading = falseसफलता और असफल कॉलबैक, दोनों में डालने के बजाय एक साफ-सुथरा तरीका, इसे अंदर रखना है .finally()। यह ऐसा दिखेगा:mySvc.get().then(success, fail).finally(function() { $scope.loading = false; });
टॉम

44

यहाँ एक का उपयोग कर एक संस्करण है directiveऔर ng-hide

यह कोणीय सेवा के माध्यम से सभी कॉल के दौरान लोडर को दिखाएगा $http

टेम्पलेट में:

<div class="loader" data-loading></div>

निर्देश:

angular.module('app')
  .directive('loading', ['$http', function ($http) {
    return {
      restrict: 'A',
      link: function (scope, element, attrs) {
        scope.isLoading = function () {
          return $http.pendingRequests.length > 0;
        };
        scope.$watch(scope.isLoading, function (value) {
          if (value) {
            element.removeClass('ng-hide');
          } else {
            element.addClass('ng-hide');
          }
        });
      }
    };
}]);

ng-hideतत्व पर वर्ग का उपयोग करके , आप jquery से बच सकते हैं।


अनुकूलित करें: एक जोड़ें interceptor

यदि आप लोडिंग-इंटरसेप्टर बनाते हैं, तो आप एक शर्त के आधार पर लोडर को दिखा / छिपा सकते हैं।

निर्देश:

var loadingDirective = function ($rootScope) {
  return function ($scope, element, attrs) {
      $scope.$on("loader_show", function () {
          return element.removeClass('ng-hide');
      });
      return $scope.$on("loader_hide", function () {
          return element.addClass('ng-hide');
      });
  };
};

इंटरसेप्टर:

  • उदाहरण के लिए: spinnerजब नहीं दिखाresponse.background === true;
  • अवरोधन requestऔर / या responseसेट $rootScope.$broadcast("loader_show");या$rootScope.$broadcast("loader_hide");

इंटरसेप्टर लिखने पर अधिक जानकारी


@punkrockpolly मेरे विशिष्ट परिदृश्य में, मेरे पास सेवा को कॉल करने वाले दो इंडिविजुअल घटक हैं। लेकिन यह सिर्फ उनमें से एक के लिए काम करता है, क्या मुझे इस पुन: प्रयोज्य बनाने के लिए एक पैरामीटर या कुछ पारित करना चाहिए?
RicardoGonzales

@razorblade यह $httpकिसी भी सेवा में आपके द्वारा कॉल करने पर कभी भी स्पिन करेगा ।
punkrockpolly

31

यदि आप ngResource का उपयोग कर रहे हैं, तो किसी ऑब्जेक्ट का $ हल किया गया विशेषता लोडर के लिए उपयोगी है:

एक संसाधन के लिए इस प्रकार है:

var User = $resource('/user/:id', {id:'@id'});
var user = User.get({id: 1})

आप लोडर को संसाधन ऑब्जेक्ट के $ हल किए गए विशेषता से लिंक कर सकते हैं:

<div ng-hide="user.$resolved">Loading ...</div>


13

अभी खोजा है angular-busy निर्देश की जो कुछ async कॉल के आधार पर थोड़ा लोडर दिखाता है।

उदाहरण के लिए, यदि आपको एक करना है GET, तो अपने वादे का संदर्भ दें $scope,

$scope.req = $http.get('http://google.fr');

और इसे कॉल करें:

<div cg-busy="req"></div>

यहाँ है GitHub

आप इसका उपयोग करके भी इसे स्थापित कर सकते हैं bower(अपनी परियोजना निर्भरता को अद्यतन करना न भूलें):

bower install angular-busy --save

मैं प्रलेखन में "कुछ तत्व को अक्षम करने" का तरीका नहीं खोज सका। क्या आप बता सकते हैं कैसे? उदाहरण के लिए, मैं एक बटन अक्षम करना चाहता हूं जबकि स्पिनर दिखाया गया है।
c4k

कोणीय-व्यस्त केवल आपके तत्व पर एक मुखौटा लगाता है, मुझे नहीं लगता कि आप एक बटन को अक्षम कर सकते हैं जैसा आप करना चाहते हैं, लेकिन आप इस छाप को देने के लिए एक खाली टेम्पलेट के साथ उस पर पृष्ठभूमि सेट कर सकते हैं। मैं एक देशी वक्ता नहीं हूँ, भ्रम के लिए खेद है :)
बाल्त्झार

ठीक है, मैंने आपके उत्तर को उसी भ्रम के कारण किसी और को रोकने के लिए संपादित किया है। एक फ्रांसीसी दूसरे से अंग्रेजी बोलने वाला फ्रांसीसी हमेशा भ्रमित होता है :)
c4k

5

यदि आप किसी सेवा / कारखाने के भीतर अपने एपीआई कॉल को लपेट रहे हैं, तो आप लोडिंग काउंटर को ट्रैक कर सकते हैं (प्रति उत्तर और @JMaylin द्वारा एक साथ उत्कृष्ट सुझाव), और एक निर्देश के माध्यम से लोडिंग काउंटर को देखें। या उसके किसी भी संयोजन।

एपीआई WRAPPER

yourModule
    .factory('yourApi', ['$http', function ($http) {
        var api = {}

        //#region ------------ spinner -------------

        // ajax loading counter
        api._loading = 0;

        /**
         * Toggle check
         */
        api.isOn = function () { return api._loading > 0; }

        /**
         * Based on a configuration setting to ignore the loading spinner, update the loading counter
         * (for multiple ajax calls at one time)
         */
        api.spinner = function(delta, config) {
            // if we haven't been told to ignore the spinner, change the loading counter
            // so we can show/hide the spinner

            if (NG.isUndefined(config.spin) || config.spin) api._loading += delta;

            // don't let runaway triggers break stuff...
            if (api._loading < 0) api._loading = 0;

            console.log('spinner:', api._loading, delta);
        }
        /**
         * Track an ajax load begin, if not specifically disallowed by request configuration
         */
        api.loadBegin = function(config) {
            api.spinner(1, config);
        }
        /**
         * Track an ajax load end, if not specifically disallowed by request configuration
         */
        api.loadEnd = function (config) {
            api.spinner(-1, config);
        }

        //#endregion ------------ spinner -------------

        var baseConfig = {
            method: 'post'
            // don't need to declare `spin` here
        }

        /**
         * $http wrapper to standardize all api calls
         * @param args stuff sent to request
         * @param config $http configuration, such as url, methods, etc
         */
        var callWrapper = function(args, config) {
            var p = angular.extend(baseConfig, config); // override defaults

            // fix for 'get' vs 'post' param attachment
            if (!angular.isUndefined(args)) p[p.method == 'get' ? 'params' : 'data'] = args;

            // trigger the spinner
            api.loadBegin(p);

            // make the call, and turn of the spinner on completion
            // note: may want to use `then`/`catch` instead since `finally` has delayed completion if down-chain returns more promises
            return $http(p)['finally'](function(response) {
                api.loadEnd(response.config);
                return response;
            });
        }

        api.DoSomething = function(args) {
            // yes spinner
            return callWrapper(args, { cache: true });
        }
        api.DoSomethingInBackground = function(args) {
            // no spinner
            return callWrapper(args, { cache: true, spin: false });
        }

        // expose
        return api;
    });

स्पिनर प्रत्यक्ष

(function (NG) {
    var loaderTemplate = '<div class="ui active dimmer" data-ng-show="hasSpinner()"><div class="ui large loader"></div></div>';

    /**
     * Show/Hide spinner with ajax
     */
    function spinnerDirective($compile, api) {
        return {
            restrict: 'EA',
            link: function (scope, element) {
                // listen for api trigger
                scope.hasSpinner = api.isOn;

                // attach spinner html
                var spin = NG.element(loaderTemplate);
                $compile(spin)(scope); // bind+parse
                element.append(spin);
            }
        }
    }

    NG.module('yourModule')
        .directive('yourApiSpinner', ['$compile', 'yourApi', spinnerDirective]);
})(angular);

उपयोग

<div ng-controller="myCtrl" your-api-spinner> ... </div>

5

पेज लोड और मोडल के लिए, सबसे आसान तरीका ng-showनिर्देश का उपयोग करना है और एक स्कोप डेटा वैरिएबल का उपयोग करना है। कुछ इस तरह:

ng-show="angular.isUndefined(scope.data.someObject)".

यहाँ, जबकि someObjectअपरिभाषित है, स्पिनर दिखाएगा। एक बार जब सेवा डेटा के साथ वापस आ जाती है और someObjectआबादी हो जाती है, तो स्पिनर अपने छिपे हुए राज्य में वापस आ जाएगा।


3

स्पिनर को जोड़ने का यह सबसे आसान तरीका है: -

आप इन सुंदर स्पिनरों में से किसी एक के टैग के साथ एनजी-शो का उपयोग कर सकते हैं http://tobiasahlin.com/spinkit/ {{यह मेरा पेज नहीं है}}

और तब आप इस तरह के तर्क का उपयोग कर सकते हैं

//ajax start
    $scope.finderloader=true;
    
          $http({
    method :"POST",
    url : "your URL",
  data: { //your data
     
     }
  }).then(function mySucces(response) {
    $scope.finderloader=false;
      $scope.search=false;          
    $scope.myData =response.data.records;
  });
     
    //ajax end 
    
<div ng-show="finderloader" class=spinner></div>
//add this in your HTML at right place


3
Based on Josh David Miller response:

  <body>
  <header>
  </header>
<div class="spinner" ng-show="loading">
  <div class="loader" ></div>
</div>

<div ng-view=""></div>

<footer>
</footer>

</body>

इस सीएसएस को जोड़ें:

    .loader {
  border: 16px solid #f3f3f3;
  border-radius: 50%;
  border-top: 16px solid #3498db;
  border-bottom : 16px solid black;
  width: 80px;
  height: 80px;
  -webkit-animation: spin 2s linear infinite;
  animation: spin 2s linear infinite;
  position: absolute;
  top: 45%;
  left: 45%;
}

@-webkit-keyframes spin {
  0% { -webkit-transform: rotate(0deg); }
  100% { -webkit-transform: rotate(360deg); }
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}


.spinner{
  width: 100%;
height: 100%;
z-index: 10000;
position: absolute;
top: 0;
left: 0;
margin: 0 auto;
text-align: center;
vertical-align: middle;
background: white;
opacity: 0.6;
}

और सिर्फ अपने कोणीय जोड़ में:

$ rootScope.loading = false; $ rootSope.loading = true; -> जब $ http.get समाप्त होता है।


2

@Bulltorious से शानदार उत्तर के मेरे संस्करण को साझा करते हुए, नए कोणीय बिल्ड के लिए अपडेट किया गया (मैंने इस कोड के साथ संस्करण 1.5.8 का उपयोग किया), और एक साथ काउंटर का उपयोग करने के लिए @ JMaylin के विचार को भी शामिल किया ताकि एक साथ कई अनुरोधों के लिए मजबूत हो सके और कुछ न्यूनतम मिलीसेकंड से कम संख्या वाले अनुरोधों के लिए एनीमेशन दिखाने को छोड़ने का विकल्प:

var app = angular.module('myApp');
var BUSY_DELAY = 1000; // Will not show loading graphic until 1000ms have passed and we are still waiting for responses.

app.config(function ($httpProvider) {
  $httpProvider.interceptors.push('busyHttpInterceptor');
})
  .factory('busyHttpInterceptor', ['$q', '$timeout', function ($q, $timeout) {
    var counter = 0;
    return {
      request: function (config) {
        counter += 1;
        $timeout(
          function () {
            if (counter !== 0) {
              angular.element('#busy-overlay').show();
            }
          },
          BUSY_DELAY);
        return config;
      },
      response: function (response) {
        counter -= 1;
        if (counter === 0) {
          angular.element('#busy-overlay').hide();
        }
        return response;
      },
      requestError: function (rejection) {
        counter -= 1;
        if (counter === 0) {
          angular.element('#busy-overlay').hide();
        }
        return rejection;
      },
      responseError: function (rejection) {
        counter -= 1;
        if (counter === 0) {
          angular.element('#busy-overlay').hide();
        }
        return rejection;
      }
    }
  }]);

2

Http अनुरोध कॉल प्रबंधित करने के लिए आप कोणीय इंटरसेप्टर का उपयोग कर सकते हैं

  <div class="loader">
    <div id="loader"></div>
  </div>

<script>
    var app = angular.module("myApp", []);

    app.factory('httpRequestInterceptor', ['$rootScope', '$location', function ($rootScope, $location) {
        return {
            request: function ($config) {
                $('.loader').show();
                return $config;
            },
            response: function ($config) {
                $('.loader').hide();
                return $config;
            },
            responseError: function (response) {
                return response;
            }
        };
    }]);

    app.config(['$stateProvider', '$urlRouterProvider', '$httpProvider',
        function ($stateProvider, $urlRouterProvider, $httpProvider) {
            $httpProvider.interceptors.push('httpRequestInterceptor');
        }]);

</script>

https://stackoverflow.com/a/49632155/4976786


2

इंटरसेप्टर या jQuery के बिना सरल तरीका

स्पिनर को दिखाने का यह एक सरल तरीका है जिसमें किसी तीसरे पक्ष के पुस्तकालय, इंटरसेप्टर या jQuery की आवश्यकता नहीं होती है।

नियंत्रक में, एक ध्वज सेट और रीसेट करें।

function starting() {
    //ADD SPINNER
    vm.starting = true;
    $http.get(url)
      .then(function onSuccess(response) {
        vm.data = response.data;
    }).catch(function onReject(errorResponse) {
        console.log(errorResponse.status);
    }).finally(function() {
        //REMOVE SPINNER
        vm.starting = false;
    });
};

HTML में, ध्वज का उपयोग करें:

<div ng-show="vm.starting">
    <img ng-src="spinnerURL" />
</div>

<div ng-hide="vm.starting">
    <p>{{vm.data}}</p>
</div>

vm.startingध्वज सेट है trueजब एक्सएचआर शुरू होती है और मंजूरी दे दी जब एक्सएचआर पूरा करती है।


1

यह मेरे लिए अच्छा काम करता है:

HTML:

  <div id="loader" class="ng-hide" ng-show="req.$$state.pending">
    <img class="ajax-loader" 
         width="200" 
         height="200" 
         src="/images/spinner.gif" />
  </div>

कोणीय:

  $scope.req = $http.get("/admin/view/"+id).success(function(data) {          
      $scope.data = data;
  });

जबकि $ http से लौटाया गया वादा लंबित है, एनजी-शो इसे "सत्य" होने का मूल्यांकन करेगा। वादा हल हो जाने के बाद यह स्वचालित रूप से अपडेट हो जाता है ... जो हम चाहते हैं, वही है।


यह ऐसा करने का गतिशील तरीका नहीं है।
उमैर हामिद

क्या आप यह समझा सकते हैं कि आप यह क्यों मानते हैं कि यह लक्ष्य हासिल करने का एक गतिशील तरीका नहीं है। इससे दूसरों को इस पोस्ट को पढ़ने में मदद मिलेगी। धन्यवाद।
नम

मेरे आवेदन में मेरे कई अनुरोध हैं। $ गुंजाइश.req केवल एकल अनुरोध के लिए काम करेगा। जब यह विशेष अनुरोध पूरा लोडर छिपाएगा और अन्य अनुरोधों को पूरा करने के लिए इंतजार नहीं करेगा। इसे प्राप्त करने का सबसे अच्छा तरीका इंटरसेप्टर्स का उपयोग करना है।
उमैर हामिद

1

Http अनुरोध पर लोडिंग बार दिखाने के लिए इंटरसर्च के बाद उपयोग किया जाता है

'use strict';
appServices.factory('authInterceptorService', ['$q', '$location', 'localStorage','$injector','$timeout', function ($q, $location, localStorage, $injector,$timeout) {

var authInterceptorServiceFactory = {};
var requestInitiated;

//start loading bar
var _startLoading = function () {
   console.log("error start loading");
   $injector.get("$ionicLoading").show();

}

//stop loading bar
var _stopLoading = function () {
    $injector.get("$ionicLoading").hide();
}

//request initiated
var _request = function (config) {
     requestInitiated = true;
    _startLoading();
    config.headers = config.headers || {};
    var authDataInitial = localStorage.get('authorizationData');
    if (authDataInitial && authDataInitial.length > 2) {
        var authData = JSON.parse(authDataInitial);
        if (authData) {
            config.headers.Authorization = 'Bearer ' + authData.token;
        }
    }
    return config;
}

//request responce error
var _responseError = function (rejection) {
   _stopLoading();
    if (rejection.status === 401) {
        $location.path('/login');
    }
    return $q.reject(rejection);
}

//request error
var _requestError = function (err) {
   _stopLoading();
   console.log('Request Error logging via interceptor');
   return err;
}

//request responce
var _response = function(response) {
    requestInitiated = false;

   // Show delay of 300ms so the popup will not appear for multiple http request
   $timeout(function() {

        if(requestInitiated) return;
        _stopLoading();
        console.log('Response received with interceptor');

    },300);

return response;
}



authInterceptorServiceFactory.request = _request;
authInterceptorServiceFactory.responseError = _responseError;
authInterceptorServiceFactory.requestError = _requestError;
authInterceptorServiceFactory.response = _response;

return authInterceptorServiceFactory;
}]);

0
.factory('authHttpResponseInterceptor', ['$q', function ($q) {
        return {
            request: function(config) {
                angular.element('#spinner').show();
                return config;
            },
            response : function(response) {
                angular.element('#spinner').fadeOut(3000);
                return response || $q.when(response);
            },
            responseError: function(reason) {
                angular.element('#spinner').fadeOut(3000);
                return $q.reject(reason);
            }
        };
    }]);



 .config(['$routeProvider', '$locationProvider', '$translateProvider', '$httpProvider',
            function ($routeProvider, $locationProvider, $translateProvider, $httpProvider) {
                $httpProvider.interceptors.push('authHttpResponseInterceptor');
    }
]);

in your Template
<div id="spinner"></div>


css   

#spinner,
#spinner:after {
  border-radius: 50%;
  width: 10em;
  height: 10em;
  background-color: #A9A9A9;
  z-index: 10000;
  position: absolute;
  left: 50%;
  bottom: 100px;
}
@-webkit-keyframes load8 {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}
@keyframes load8 {
  0% {
    -webkit-transform: rotate(0deg);
    transform: rotate(0deg);
  }
  100% {
    -webkit-transform: rotate(360deg);
    transform: rotate(360deg);
  }
}

1
कोड-केवल उत्तर बहुत उपयोगी नहीं हैं।
फैंटमैक्सएक्स

0

इस कोड के साथ निर्देश बनाएँ:

$scope.$watch($http.pendingRequests, toggleLoader);

function toggleLoader(status){
  if(status.length){
    element.addClass('active');
  } else {
    element.removeClass('active');
  }
}

0

विभिन्न यूआरएल परिवर्तनों के बीच लोडिंग दिखाने का एक और उपाय है:

$rootScope.$on('$locationChangeStart', function() {
  $scope.loading++;
});

$rootScope.$on('$locationChangeSuccess', function() {
  $timeout(function() {
    $scope.loading--;
  }, 300);
});

और फिर मार्कअप में बस स्पिनर के साथ टॉगल करें ng-show="loading"

यदि आप इसे ajax अनुरोधों पर प्रदर्शित करना चाहते हैं $scope.loading++तो बस अनुरोध शुरू होने पर जोड़ें और इसे समाप्त होने पर जोड़ें $scope.loading--


0

आप कुछ इस तरह की कोशिश कर सकते हैं:

निर्देश बनाएँ:

myApp.directive('loader', function () {
    return {
        restrict: 'A',
        scope: {cond: '=loader'},
        template: '<span ng-if="isLoading()" class="soft"><span class="fa fa-refresh fa-spin"></span></span>',
        link: function (scope) {
            scope.isLoading = function() {
                var ret = scope.cond === true || (
                        scope.cond &&
                        scope.cond.$$state &&
                        angular.isDefined(scope.cond.$$state.status) &&
                        scope.cond.$$state.status === 0
                    );
                return ret;
            }
        }
    };
}); 

फिर आप कुछ इस तरह से mainttrl को जोड़े

    // Return TRUE if some request is LOADING, else return FALSE
    $scope.isLoading = function() {
        return $http.pendingRequests.length > 0;
    };

और HTML इस तरह दिख सकता है:

<div class="buttons loader">
    <span class="icon" loader="isLoading()"></span>
</div>

0

निम्नलिखित तरीके सभी अनुरोधों पर ध्यान देंगे, और सभी अनुरोधों को पूरा करने के बाद ही छिपाएँ:

app.factory('httpRequestInterceptor', function(LoadingService, requestCount) {
    return {
        request: function(config) {
            if (!config.headers.disableLoading) {
                requestCount.increase();
                LoadingService.show();
            }
            return config;
        }
    };
}).factory('httpResponseInterceptor', function(LoadingService, $timeout, error, $q, requestCount) {
    function waitAndHide() {
        $timeout(function() {
            if (requestCount.get() === 0){
                LoadingService.hide();
            }
            else{
                waitAndHide();
            }
        }, 300);
    }

    return {
        response: function(config) {
            requestCount.descrease();
            if (requestCount.get() === 0) {
                waitAndHide();
            }
            return config;
        },
        responseError: function(config) {
            requestCount.descrease();
            if (requestCount.get() === 0) {
                waitAndHide();
            }
            var deferred = $q.defer();
            error.show(config.data, function() {
                deferred.reject(config);
            });
            return deferred.promise;
        }
    };
}).factory('requestCount', function() {
    var count = 0;
    return {
        increase: function() {
            count++;
        },
        descrease: function() {
            if (count === 0) return;
            count--;
        },
        get: function() {
            return count;
        }
    };
})


0

चूंकि स्थिति की कार्यक्षमता : हाल ही में परिवर्तित हुई, मुझे सभी तत्वों के ऊपर gif लोडर दिखाने में कठिनाई हुई, इसलिए मुझे कोणीय इनबिल्ट jQuery का उपयोग करना पड़ा ।

एचटीएमएल

<div ng-controller="FetchController">
      <div id="spinner"></div>
</div>

सीएसएस

#spinner {display: none}
body.spinnerOn #spinner { /* body tag not necessary actually */
   display: block;
   height: 100%;
   width: 100%;
   background: rgba(207, 13, 48, 0.72) url(img/loader.gif) center center no-repeat;
   position: fixed;
   top: 0;
   left: 0;
   z-index: 9999;
}
body.spinnerOn main.content { position: static;} /* and whatever content needs to be moved below your fixed loader div */

नियंत्रक

app.controller('FetchController', ['$scope', '$http', '$templateCache', '$location', '$q',
function($scope, $http, $templateCache, $location, $q) {

angular.element('body').addClass('spinnerOn'); // add Class to body to show spinner

$http.post( // or .get(
    // your data here
})
.then(function (response) {
    console.info('success');     
    angular.element('body').removeClass('spinnerOn'); // hide spinner

    return response.data;               
}, function (response) {                   
    console.info('error'); 
    angular.element('body').removeClass('spinnerOn'); // hide spinner
});

})

उम्मीद है की यह मदद करेगा :)


0

सभी उत्तर हैं या जटिल हैं, या हर अनुरोध पर कुछ चर निर्धारित करने की आवश्यकता है, जो कि अगर हम DRY अवधारणा को जानते हैं, तो बहुत गलत अभ्यास है। यहाँ सरल इंटरसेप्टर उदाहरण, मैंने माउस को प्रतीक्षा पर रखा है जब अजाक्स शुरू होता है और जब अजाक्स समाप्त होता है तो इसे ऑटो पर सेट करता है।

$httpProvider.interceptors.push(function($document) {
    return {
     'request': function(config) {
         // here ajax start
         // here we can for example add some class or show somethin
         $document.find("body").css("cursor","wait");

         return config;
      },

      'response': function(response) {
         // here ajax ends
         //here we should remove classes added on request start

         $document.find("body").css("cursor","auto");

         return response;
      }
    };
  });

कोड को एप्लिकेशन कॉन्फिगर में जोड़ा जाना है app.config। मैंने दिखाया कि लोड करने की स्थिति पर माउस को कैसे बदला जाए, लेकिन वहां किसी लोडर सामग्री को दिखाना / छिपाना, या जोड़ना संभव है, कुछ सीएसएस वर्गों को हटा दें जो लोडर दिखा रहे हैं।

इंटरसेप्टर हर ऐजैक्स कॉल पर चलेगा, इसलिए हर http कॉल पर विशेष बूलियन वैरिएबल ($ गुंजाइश.loading = true / false आदि) बनाने की कोई आवश्यकता नहीं है ।


0

यहाँ मेरा कार्यान्वयन, एनजी-शो और अनुरोध काउंटर के रूप में सरल है।

यह $ http के लिए सभी अनुरोधों के लिए एक नई सेवा का उपयोग करता है:

myApp.service('RqstSrv', [ '$http', '$rootScope', function($http, $rootScope) {
    var rqstService = {};

    rqstService.call = function(conf) {

        $rootScope.currentCalls = !isNaN($rootScope.currentCalls) ?  $rootScope.currentCalls++ : 0;

        $http(conf).then(function APICallSucceed(response) {
            // Handle success
        }, function APICallError(response) {
            // Handle error
        }).then(function() {
            $rootScope.currentCalls--;
        });
    }
} ]);

और फिर आप वर्तमान कॉल की संख्या के आधार पर अपने लोडर आधार का उपयोग कर सकते हैं:

<img data-ng-show="currentCalls > 0" src="images/ajax-loader.gif"/>

0

यदि आप हर http अनुरोध कॉल के लिए लोडर दिखाना चाहते हैं तो आप http अनुरोध कॉल का उपयोग कर सकते हैं http अनुरोध कॉल,

यहाँ एक नमूना कोड है

<body data-ng-app="myApp">
<div class="loader">
    <div id="loader"></div>
</div>

<script>
    var app = angular.module("myApp", []);

    app.factory('httpRequestInterceptor', ['$rootScope', '$location', function ($rootScope, $location) {
        return {
            request: function ($config) {
                $('.loader').show();
                return $config;
            },
            response: function ($config) {
                $('.loader').hide();
                return $config;
            },
            responseError: function (response) {
                return response;
            }
        };
    }]);

    app.config(['$stateProvider', '$urlRouterProvider', '$httpProvider',
        function ($stateProvider, $urlRouterProvider, $httpProvider) {
            $httpProvider.interceptors.push('httpRequestInterceptor');
        }]);

</script>
</body>

0

बस एनजी-शो और एक बूलियन का उपयोग करें

किसी निर्देश का उपयोग करने की आवश्यकता नहीं, जटिल होने की आवश्यकता नहीं।

यहाँ बटन सबमिट करने के लिए या जहाँ आप स्पिनर होना चाहते हैं, उसके आगे कोड है:

<span ng-show="dataIsLoading">
  <img src="http://www.nasa.gov/multimedia/videogallery/ajax-loader.gif" style="height:20px;"/>
</span>

और फिर अपने नियंत्रक में:

$scope.dataIsLoading = true

let url = '/whatever_Your_URL_Is'
$http.get(url)
.then(function(response) {
  $scope.dataIsLoading = false
})

-1

यहाँ मेरा समाधान है जो मुझे लगता है कि बहुत आसान है कि दूसरे ने यहां पोस्ट किया है। यह सुनिश्चित नहीं है कि यह "सुंदर" कैसे है, हालांकि, लेकिन इसने मेरे सभी मुद्दों को हल कर दिया

मेरे पास "लोडिंग" नामक एक सीएसएस शैली है

.loading { display: none; }

लोडिंग डिव के लिए html कुछ भी हो सकता है, लेकिन मैंने कुछ FontAwesome आइकनों और वहां की स्पिन विधि का उपयोग किया है:

<div style="text-align:center" ng-class="{ 'loading': !loading }">
    <br />
    <h1><i class="fa fa-refresh fa-spin"></i> Loading data</h1>
</div>

जिन तत्वों को आप छिपाना चाहते हैं, उन पर यह लिखें:

<something ng-class="{ 'loading': loading }" class="loading"></something>

और फ़ंक्शन में मैंने इसे लोड पर सेट किया है।

(function (angular) {
    function MainController($scope) {
        $scope.loading = true

मैं hubProxy.client.allLocks फ़ंक्शन में सिग्नलआर का उपयोग कर रहा हूं (जब इसके ताले के माध्यम से जा रहा है) तो मैं झटके डालता हूं

 $scope.loading = false
 $scope.$apply();

यह भी {{someField}} को छुपाता है जब पृष्ठ लोड हो रहा है क्योंकि मैं लोडिंग क्लास को लोड पर सेट कर रहा हूं और AngularJS इसे बाद में हटा देता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.