Evento cargado de imagen para ng-src en AngularJS

106

Tengo imágenes que parecen <img ng-src="dynamically inserted url"/>. Cuando se carga una sola imagen, necesito aplicar el método iScroll refresh () para que la imagen sea desplazable.

¿Cuál es la mejor manera de saber cuándo una imagen está completamente cargada para ejecutar alguna devolución de llamada?

Sergei Basharov
fuente
1
Eche un vistazo a los interceptores de respuesta $ http . Puede usar esto para registrar una devolución de llamada cuando se resuelva la promesa
Mark Meyer

Respuestas:

185

Aquí hay un ejemplo de cómo llamar a image onload http://jsfiddle.net/2CsfZ/2/

La idea básica es crear una directiva y agregarla como atributo a la etiqueta 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 />
Mikach
fuente
1
¿Qué pasa con una devolución de llamada de falla?
Oleg Belousov
3
¿Qué pasa con la imagen progresiva?
Nguyễn Đức Long
148

Modifiqué esto un poco para que $scopese puedan llamar a métodos personalizados :

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

La directiva:

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

Espero que alguien lo encuentre MUY útil. Gracias @mikach

La doThis()función sería entonces un método $ scope

Pedro
fuente
3
Eso es correcto. La solución de Mikach no funcionó para mí hasta que usé $ apply () como tú.
Jeremy Thille
Esta es la mejor de las respuestas proporcionadas. También elimina totalmente la necesidad de cualquier carga JQUERY.
Noel Baron
Gracias por poner punto y coma para que la pelusa no explote.
Richard
esto me da este error: code.angularjs.org/1.4.9/docs/error/$rootScope/…
Paulo Roberto Rosa
9

@ Oleg Tikhonov: Acabo de actualizar el código anterior .. @ mikach Gracias ..)

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');
        });
    }
  };
});
Kailash
fuente
1
Podría ser mejor tener eso en una directiva 'imageonerror' para que pueda realizar una acción diferente.
Jon Catmull
5

Mi respuesta:

 var img = new Image();
 var imgUrl = "path_to_image.jpg";
 img.src = imgUrl;
 img.onload = function () {
      $scope.pic = img.src;
 }
Rodrigo Andrade
fuente
¡Exactamente lo que estaba buscando!
Zohab Ali
4

Acabo de actualizar el código anterior.

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

y directiva ...

    .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);
                });
            }
        };
    })
Ramiro España
fuente
0

Básicamente, esta es la solución que terminé usando.

$ apply () solo debe ser utilizado por fuentes externas en las circunstancias adecuadas.

en lugar de usar aplicar, lancé la actualización del alcance al final de la pila de llamadas. Funciona tan bien como "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);
            });
        }
    };

}]);
Doug
fuente
¿Qué quiere decir con " $apply()sólo debe ser utilizado por fuentes externas"? no estoy siguiendo.
Genuinefafa
@genuinefafa Lo que quiere decir con 'fuentes externas' es código no angular. Entonces, por ejemplo, si está utilizando un detector de eventos JS genérico para llamar al código que cambia $ scope, necesitaría usar $ apply allí. Pero si es un evento Angular o una función $ scope, no necesita $ apply porque el ciclo $ digest ya se está ejecutando desde métodos Angular.
tpartee