Événement chargé d'image dans pour ng-src dans AngularJS


106

J'ai des images qui ressemblent à <img ng-src="dynamically inserted url"/>. Lorsqu'une seule image est chargée, je dois appliquer la méthode iScroll refresh () pour que l'image puisse faire défiler.

Quelle est la meilleure façon de savoir quand une image est complètement chargée pour exécuter un rappel?


1
Jetez un œil à $ http Response Interceptors . Vous pouvez l'utiliser pour enregistrer un rappel lorsque la promesse se résout
Mark Meyer

Réponses:


185

Voici un exemple comment appeler l'image onload http://jsfiddle.net/2CsfZ/2/

L'idée de base est de créer une directive et de l'ajouter en tant qu'attribut à la balise img.

JS:

app.directive('imageonload', function() {
    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('load', function() {
                alert('image is loaded');
            });
            element.bind('error', function(){
                alert('image could not be loaded');
            });
        }
    };
});

HTML:

 <img ng-src="{{src}}" imageonload />

1
qu'en est-il d'un rappel d'échec?
Oleg Belousov

3
Et l'image progressive?
Nguyễn Đức Long

148

J'ai un peu modifié ceci pour que les $scopeméthodes personnalisées puissent être appelées:

<img ng-src="{{src}}" imageonload="doThis()" />

La directive:

.directive('imageonload', function() {
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {
                element.bind('load', function() {
                    //call the function that was passed
                    scope.$apply(attrs.imageonload);
                });
            }
        };
    })

J'espère que quelqu'un le trouvera TRÈS utile. Merci @mikach

La doThis()fonction serait alors une méthode $ scope


3
C'est correct. La solution de Mikach n'a pas fonctionné pour moi jusqu'à ce que j'utilise $ apply () comme vous l'avez fait.
Jeremy Thille

C'est la meilleure des réponses fournies. Élimine totalement le besoin de tout chargement JQUERY.
Noel Baron

Merci d'avoir mis des points-virgules pour que les peluches n'explosent pas.
richard


9

@ Oleg Tikhonov: Je viens de mettre à jour le code précédent .. @ mikach Merci ..)

app.directive('imageonload', function() {
  return {
    restrict: 'A',
    link: function(scope, element, attrs) {
        element.bind('load', function() {
            alert('image is loaded');
        });
        element.bind('error', function(){
             alert('image could not be loaded');
        });
    }
  };
});

1
Il vaudrait peut-être mieux avoir cela dans une directive «imageonerror» afin que vous puissiez effectuer une action différente.
Jon Catmull

5

Ma réponse:

 var img = new Image();
 var imgUrl = "path_to_image.jpg";
 img.src = imgUrl;
 img.onload = function () {
      $scope.pic = img.src;
 }

exactement ce que je cherchais!
Zohab Ali

4

Je viens de mettre à jour le code précédent.

<img ng-src="{{urlImg}}" imageonload="myOnLoadImagenFunction">

et directive ...

    .directive('imageonload', function() {
        return {
            restrict: 'A',
            link: function(scope, element, attrs) {
                element.bind('load', function() {
                    scope.$apply(attrs.imageonload)(true);
                });
                element.bind('error', function(){
                  scope.$apply(attrs.imageonload)(false);
                });
            }
        };
    })

0

En gros, c'est la solution que j'ai fini par utiliser.

$ apply () ne doit être utilisé par des sources externes que dans les bonnes circonstances.

plutôt que d'utiliser apply, j'ai jeté la mise à jour de la portée à la fin de la pile d'appels. Fonctionne aussi bien que "scope. $ Apply (attrs.imageonload) (true);".

window.app.directive("onImageload", ["$timeout", function($timeout) {

    function timeOut(value, scope) {
        $timeout(function() {
            scope.imageLoaded = value;
        });
    }

    return {
        restrict: 'A',
        link: function(scope, element, attrs) {
            element.bind('load', function() {
                timeOut(true, scope);
            }).bind('error', function() {
                timeOut(false, scope);
            });
        }
    };

}]);

qu'entendez-vous par « $apply()ne doit être utilisé que par des sources externes»? je ne suis pas.
Genuinefafa

@g Genuinefafa Ce qu'il entend par «sources externes» est du code non angulaire. Ainsi, par exemple, si vous utilisez un écouteur d'événements JS générique pour appeler du code qui change $ scope, vous devrez utiliser $ apply ici. Mais s'il s'agit d'un événement Angular ou d'une fonction $ scope, vous n'avez pas besoin de $ apply car le cycle $ digest s'exécute déjà à partir de méthodes Angular.
tpartee
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.