web-dev-qa-db-fra.com

AngularJS: Comment afficher le préchargement ou le chargement jusqu'au chargement complet de la page?

J'ai un site de galerie d'images où je récupère toutes les images et les données liées aux images de la base de données au format json dans mon contrôleur, puis en utilisant ng-repeat, je les lie avec le code HTML. Maintenant, les données sont chargées tôt mais les images sont retardées, de sorte que les images sont dispersées. Comment résoudre ce problème Je ne veux pas utiliser setTimeOut.

L'exemple de code est comme ci-dessous: -

<!DOCTYPE html>
<html lang="en" class="no-js" ng-app="cps">
<body ng-controller="CPSController">
<div>
<li ng-repeat="image in images" class="shown">
                <a id="{{image.imageid}}" ng-click="openimage(image.imageid)">
                    <img idx="id-thumb-{{$index}}" ng-src="/imagedisplay/{{image.imageid}}" alt="" style="">
                    <div class="meta_info">
                        <h3>{{image.imagename}}.</h3>
                        <div class="callto">
                            <div class="actions">
                                <span><img src="img/artist.svg" alt="">{{image.ownername}}</span>
                                <span><img src="img/likes.svg" alt="">{{image.likes}}</span>
                                <span><img src="img/views_small.svg" alt="">{{image.views}}</span>
                            </div>
                            <div class="category">
                                Art Category
                            </div>
                        </div>
                    </div>
                </a>
            </li>

</div>
</body>
</html>

<script>

    var cps = angular.module('cps', []);
    cps.controller('CPSController', function($scope, $http, $compile){
        $scope.products = [];
        $http.get("/alldata/").success(function(data){
             if(data != "null")
             {
               for(i=data.length-1; i>=0; i--){
                 $scope.products.Push(data[i]);
                }
                $scope.sendOrder('views', 'likes', 'timestamp', 2);
              }else{
                //$('#noImages').show();
              }

           /*setTimeout(function(){
                $("[idx^='id-thumb']").show();
            });*/
        });
     });
</script>
11
Anirban Datta

# UPDATE [August 2017]

Même réponse que ci-dessous, sauf que nous pourrions utiliser l'événement load sur window au lieu de DOMContentLoaded sur document. Cela garantira que tous les actifs (tels que les images) de la window sont chargés.

window.addEventListener("load", function(event) {
    ...
})

Nous n'avons pas à forcer Angular où Vanilla javascript peut suffire. Voici comment cela a fonctionné pour mon projet AngularJS

Ajouté ceci à la balise body. Il sera supprimé avec une balise de script une fois que HTML Content Loads

<div id="page-loading">
    <img style="display:block; margin:0 auto;" src="styles/img/page-loading.gif">
</div>

script tag juste sous l'image.

<script type="text/javascript">
    document.addEventListener("DOMContentLoaded", function(event) {
        /*Vanilla JAVASCRIPT*/
        var element = document.getElementById("page-loading");
        element.parentNode.removeChild(element);
        /* OR WITH jQuery*/
        $('#page-loading')
            .fadeOut('slow');
    });
</script>

DOMContentLoadedevent s'assurera que la callback est exécutée lorsque tout le images,fonts,js and other assets a été chargé.

Bonne chance.

17
Akash

Je ne sais pas si c'est la bonne approche, mais ce que je fais habituellement, c'est que j'ai une variable $scope.loaded qui a l'état de la page. Si la page est chargée, la div que vous voulez afficher est affichée ... Si elle est en cours de chargement, la div avec le chargeur est affichée. Jetez un coup d'oeil à ce plunk pour obtenir ce que j'essaie de dire.

Je colle le code Plunkr ici aussi.

Javascript

  var app = angular.module('plunker', []);

  app.controller('MainCtrl', function($scope, $timeout) {
    $scope.loaded = true;
    $scope.text = 'Nothing loaded yet.';

    $scope.loadSomething = function () {
      $scope.loaded = false;

      $timeout(function() {
        // Simulates loading
        $scope.text = 'Hello World';
        $scope.loaded = true;
      }, 2000);
    };
  });

HTML

<body ng-controller="MainCtrl">
<button class="btn btn-primary" ng-click="loadSomething()">Load Something</button>
<br/>
<div ng-hide="loaded">
  Loading...
</div>
<div ng-show="loaded">
  <p>{{ text }}</p>
</div>

Faites-moi savoir si vous avez besoin d'aide supplémentaire.

3
Haseeb Ahmed

Essaye ça:

angular.element($window).bind('load', function() {
 $scope.yourLoaderDiv=true;
});
1
vineet

Bien que la réponse @chotesah soit juste, je peux vous suggérer d’utiliser une méthode de préchargement pour chaque image (quelque chose comme Facebook lors du chargement de la page).

Essayez ce module module . Il vous faudra changer quelques lignes:

// Add module dependency   
angular.module('app', ['angular-preload-image']);
…
<img preload-image idx="id-thumb-{{$index}}" ng-src="/imagedisplay/{{image.imageid}}" default-image="[URL]" fallback-image="[URL]" />

Après cela, cherchez des préchargeurs d’images astucieux chez codrops .

0
terales

Pour y parvenir, je charge tous mes scripts à la fin du corps . Avant mon app-wrapper-div, je place une position fixe "loading" -div. Il est affiché immédiatement avant le chargement des autres scripts.

À la fin du corps, une fois mes scripts inclus, je place une directive angulaire qui fadeOut et supprime le chargement-div.

Le code:

<html ng-app="myApp">
<head>
  <!-- the only file loaded in the head -->
  <link rel="stylesheet" href="/.../appLoadingScreen.css"/>
</head>
<body>
    <div id="appLoadingScreen">
      <div id="appLoadingScreenCenterWrap">
        <h1 id="appLoadingScreenHeader">APP TITLE</h1>
        <p id="appLoadingScreenMsg">App is loading!</p>
      </div>
    </div>
    <div id="appWrapper" ng-controller="appCtrl"> 
    ... 
    </div>
    <!-- All stylesheet includes -->
    ...
    <!-- All script includes -->
    ...
    <script src="/.../hideLoadingScreen.js"></script>
    <hide-loading-screen></hide-loading-screen>
</body>
</html>

Et la directive hideLoadingScreen:

(function() {
  var app = angular.module('appModule');
  app.directive('hideLoadingScreen', function($timeout) {
    return {
      restrict: 'E',
      link: function() {
        $timeout(function() {
          $("#appLoadingScreen").fadeOut(600, function(){$(this).remove();});
        }, 400);
      }
    };
  });
})();
0
Ruwen

J'ai eu du mal avec le même problème. Voici ce qui fonctionne de mon côté où je montre plusieurs images de chargement pour chaque section différente en fonction des promesses. À cette fin, j'ai créé une directive.

Mon html ressemble à quelque chose comme ci-dessous.

<mi-loading promise="Loading"></mi-loading>

Directive Angularjs.

(function () {

    var module = angular.module('mi-loading', []);

    module.directive('miLoading', function () {
        return {
            restrict: 'E',
            scope: {
                promise: '='
            },

            link: function ($scope, $element, $attrs) {

                $scope.IsLoading = true;

                $scope.$watch('promise', function (prom) {
                    if (!prom) {
                        $scope.IsLoading = false;
                        return;
                    }
                    prom.success(function () { $scope.IsLoading = false; });
                });
            },
            template: '<div ng-show="IsLoading" class="spinner" style="height:300px"></div>'
        };
    });

})();

et enfin l'utilisation,

 var getData = function ()
           {
               var Promise = myservice.getMyData($scope);

               $scope.Loading = Promise;
           };

CSS

.spinner {
    min-width: 30px;
    min-height: 30px;
}

    .spinner:before {
        content: 'Loading…';
        position: absolute;
        top: 50%;
        left: 50%;
        width: 24px;
        height: 24px;
        margin-top: -13px;
        margin-left: -13px;
    }

    .spinner:not(:required):before {
        content: '';
        border-radius: 50%;
        border: 3px solid #ccc;
        /*border-top-color: #03ade0;*/
        border-top-color: #4187b5;
        animation: spinner .6s linear infinite;
        -webkit-animation: spinner .6s linear infinite;
    }
0
J-D