Zdarzenie załadowanego obrazu dla ng-src w AngularJS

106

Mam zdjęcia, które wyglądają <img ng-src="dynamically inserted url"/>. Kiedy ładowany jest pojedynczy obraz, muszę zastosować metodę iScroll refresh (), aby obraz był przewijalny.

Jaki jest najlepszy sposób, aby dowiedzieć się, kiedy obraz jest w pełni załadowany, aby uruchomić jakieś wywołanie zwrotne?

Siergiej Baszarow
źródło
1
Spójrz na $ http Response Interceptors . Możesz użyć tego do zarejestrowania oddzwonienia, gdy obietnica się spełni
Mark Meyer

Odpowiedzi:

185

Oto przykład, jak wywołać obraz onload http://jsfiddle.net/2CsfZ/2/

Podstawowym pomysłem jest utworzenie dyrektywy i dodanie jej jako atrybutu do tagu 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
źródło
1
a co z oddzwonieniem po awarii?
Oleg Belousov
3
A co z obrazem progresywnym?
Nguyễn Đức Long
148

Zmodyfikowałem to trochę, aby $scopemożna było wywołać metody niestandardowe :

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

Dyrektywa:

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

Mam nadzieję, że ktoś uzna to za BARDZO przydatne. Dzięki @mikach

doThis()Funkcja będzie wówczas metoda $ zakres

Piotr
źródło
3
To jest poprawne. Rozwiązanie Mikacha nie działało dla mnie, dopóki nie użyłem $ apply (), tak jak ty.
Jeremy Thille
To najlepsza z udzielonych odpowiedzi. Całkowicie eliminuje również potrzebę jakiegokolwiek ładowania JQUERY.
Noel Baron
Dziękuję za wstawienie średników, aby kłaczki nie wybuchły.
Richard
to daje mi ten błąd: code.angularjs.org/1.4.9/docs/error/$rootScope/ ...
Paulo Roberto Rosa
9

@ Oleg Tikhonov: Właśnie zaktualizowałem poprzedni kod .. @ mikach Dzięki ..)

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
źródło
1
Lepiej byłoby mieć to w dyrektywie „imageonerror”, aby można było wykonać inną akcję.
Jon Catmull
5

Moja odpowiedź:

 var img = new Image();
 var imgUrl = "path_to_image.jpg";
 img.src = imgUrl;
 img.onload = function () {
      $scope.pic = img.src;
 }
Rodrigo Andrade
źródło
dokładnie to, czego szukałem!
Zohab Ali
4

Właśnie zaktualizowałem poprzedni kod.

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

i dyrektywa ...

    .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 Hiszpania
źródło
0

Zasadniczo jest to rozwiązanie, z którego korzystałem.

$ apply () powinno być używane przez zewnętrzne źródła tylko w odpowiednich okolicznościach.

Zamiast używać Apply, wrzuciłem aktualizację zakresu na koniec stosu wywołań. Działa tak dobrze, jak „zakres. $ Zastosuj (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
źródło
co masz na myśli mówiąc „ $apply()powinny być używane tylko przez zewnętrzne źródła”? nie nadążam.
Genuinefafa
@g Genuinefafa Przez „zewnętrzne źródła” rozumie kod inny niż Angular. Na przykład, jeśli używasz generycznego nasłuchiwania zdarzeń JS do wywołania kodu, który zmienia $ scope, musisz tam użyć $ apply. Ale jeśli jest to zdarzenie Angular lub funkcja $ scope, nie potrzebujesz $ apply, ponieważ cykl $ digest już działa z metod Angular.
uczestnik