รูปภาพโหลดเหตุการณ์สำหรับ ng-src ใน AngularJS


106

<img ng-src="dynamically inserted url"/>ฉันมีภาพที่มองเช่น เมื่อโหลดภาพเดียวฉันต้องใช้วิธีการรีเฟรช iScroll () เพื่อให้สามารถเลื่อนภาพได้

วิธีใดที่ดีที่สุดในการทราบเมื่อรูปภาพโหลดจนเต็มเพื่อเรียกใช้การโทรกลับ


1
ลองดูที่$ http ตอบสนอง Interceptors คุณสามารถใช้สิ่งนี้เพื่อลงทะเบียนการโทรกลับเมื่อคำสัญญาได้รับการแก้ไข
Mark Meyer

คำตอบ:


185

นี่คือตัวอย่างวิธีการเรียก image onload http://jsfiddle.net/2CsfZ/2/

แนวคิดพื้นฐานคือสร้างคำสั่งและเพิ่มเป็นแอตทริบิวต์ให้กับแท็ก 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
แล้วการโทรกลับล้มเหลวล่ะ
Oleg Belousov

3
แล้วภาพโปรเกรสซีฟล่ะ?
NguyễnĐức Long

148

ฉันแก้ไขสิ่งนี้เล็กน้อยเพื่อให้$scopeสามารถเรียกวิธีการที่กำหนดเองได้:

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

คำสั่ง:

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

หวังว่าจะมีคนพบว่ามีประโยชน์มาก ขอบคุณ @mikach

doThis()ฟังก์ชั่นจากนั้นก็จะเป็นวิธีการที่ $ ขอบเขต


3
ถูกต้อง. วิธีแก้ปัญหาของ Mikach ไม่ได้ผลสำหรับฉันจนกว่าฉันจะใช้ $ apply () เหมือนที่คุณทำ
Jeremy Thille

นี่คือคำตอบที่ดีที่สุดที่มีให้ ไม่จำเป็นต้องโหลด JQUERY โดยสิ้นเชิงเช่นกัน
Noel Baron

ขอบคุณที่ใส่เครื่องหมายกึ่งโคลอนเพื่อไม่ให้ผ้าสำลีระเบิด
richard

สิ่งนี้ทำให้ฉันมีข้อผิดพลาดนี้: code.angularjs.org/1.4.9/docs/error/$rootScope/…
Paulo Roberto Rosa

9

@ Oleg Tikhonov: เพิ่งอัพเดตรหัสก่อนหน้า .. @ mikach ขอบคุณ .. )

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
อาจจะดีกว่าหากมีคำสั่ง "imageonerror" เพื่อให้คุณสามารถดำเนินการต่างๆได้
Jon Catmull


4

เพิ่งอัพเดทรหัสก่อนหน้า ..

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

และคำสั่ง ...

    .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

โดยทั่วไปนี่คือวิธีแก้ปัญหาที่ฉันใช้

ควรใช้ $ apply () โดยแหล่งข้อมูลภายนอกในสถานการณ์ที่เหมาะสมเท่านั้น

แทนที่จะใช้ Apply ฉันได้โยนขอบเขตการอัปเดตไปยังจุดสิ้นสุดของ call stack ทำงานได้ดีเท่ากับ "ขอบเขต. $ 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);
            });
        }
    };

}]);

สิ่งที่คุณหมายถึง " $apply()ควรใช้โดยแหล่งภายนอกเท่านั้น"? ฉันไม่ได้ติดตาม
Genuinefafa

@genuinefafa สิ่งที่เขาหมายถึงโดย 'แหล่งข้อมูลภายนอก' ไม่ใช่รหัสเชิงมุม ตัวอย่างเช่นหากคุณใช้ตัวฟังเหตุการณ์ JS ทั่วไปเพื่อเรียกเข้าสู่รหัสที่เปลี่ยน $ ขอบเขตคุณจะต้องใช้ $ ใช้ที่นั่น แต่ถ้าเป็นเหตุการณ์เชิงมุมหรือฟังก์ชัน $ ขอบเขตคุณไม่จำเป็นต้องใช้ $ เพราะวงจรการย่อย $ ทำงานจากวิธีการเชิงมุมอยู่แล้ว
tpartee
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.