Gambar dimuat acara untuk ng-src di AngularJS

106

Saya memiliki gambar yang terlihat seperti <img ng-src="dynamically inserted url"/>. Ketika satu gambar dimuat, saya perlu menerapkan metode iScroll refresh () sehingga membuat gambar dapat digulir.

Apa cara terbaik untuk mengetahui saat gambar dimuat sepenuhnya untuk menjalankan beberapa callback?

Sergei Basharov
sumber
1
Lihatlah $ http Response Interceptors . Anda dapat menggunakan ini untuk mendaftarkan panggilan balik ketika janji terpenuhi
Mark Meyer

Jawaban:

185

Berikut adalah contoh bagaimana memanggil image onload http://jsfiddle.net/2CsfZ/2/

Ide dasarnya adalah membuat direktif dan menambahkannya sebagai atribut ke tag 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
sumber
1
bagaimana dengan panggilan balik yang gagal?
Oleg Belousov
3
Bagaimana dengan citra progresif?
Nguyễn Đức Long
148

Saya memodifikasi ini sedikit sehingga $scopemetode khusus dapat dipanggil:

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

Arahan:

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

Semoga seseorang menganggapnya SANGAT berguna. Terima kasih @mikach

The doThis()Fungsi kemudian akan menjadi metode $ lingkup

Peter
sumber
3
Itu benar. Solusi Mikach tidak berhasil untuk saya sampai saya menggunakan $ apply () seperti yang Anda lakukan.
Jeremy Thille
Ini adalah jawaban terbaik yang diberikan. Benar-benar menghilangkan kebutuhan untuk memuat JQUERY apa pun juga.
Noel Baron
Terima kasih telah meletakkan titik koma agar serat tidak meledak.
richard
ini memberi saya kesalahan ini: code.angularjs.org/1.4.9/docs/error/$rootScope/…
Paulo Roberto Rosa
9

@ Oleg Tikhonov: Baru saja memperbarui kode sebelumnya .. @ mikach Terima kasih ..)

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
sumber
1
Mungkin lebih baik memasukkannya ke dalam perintah 'imageonerror' sehingga Anda dapat melakukan tindakan yang berbeda.
Jon Catmull
5

Jawabanku:

 var img = new Image();
 var imgUrl = "path_to_image.jpg";
 img.src = imgUrl;
 img.onload = function () {
      $scope.pic = img.src;
 }
Rodrigo Andrade
sumber
persis seperti yang saya cari!
Zohab Ali
4

Baru saja memperbarui kode sebelumnya ..

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

dan direktif ...

    .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 Spanyol
sumber
0

Pada dasarnya ini adalah solusi yang akhirnya saya gunakan.

$ apply () hanya boleh digunakan oleh sumber eksternal dalam situasi yang tepat.

daripada menggunakan apply, saya telah melempar pembaruan lingkup ke akhir tumpukan panggilan. Berfungsi sebaik "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
sumber
apa yang Anda maksud dengan " $apply()seharusnya hanya digunakan oleh sumber eksternal"? saya tidak mengikuti.
genuinefafa
@genuinefafa Yang dia maksud dengan 'sumber eksternal' adalah kode non-sudut. Jadi misalnya jika Anda menggunakan event listener JS generik untuk memanggil kode yang mengubah $ scope, Anda perlu menggunakan $ apply di sana. Tetapi jika itu adalah acara Angular atau fungsi $ scope, Anda tidak perlu $ apply karena siklus $ digest sudah berjalan dari metode Angular.
tpartee