2016-04-20 6 views
2

Um versteckt ein Standardbild zu zeigen (anstelle eines gebrochenen Bild), wenn das Bild nicht physisch vorhanden ist, verwende ich dieses Stück Code:ng-src und onerror: Gelegentlich ein gültiges Bild

<img ng-show="order.img" ng-src="{{order.img | fPath}}" onerror="this.style.display='none';"/> 
<img ng-hide="order.img" ng-src="{{'default.png' | imgPath}}" /> 

Hier sind fPath, imgPath Filter, die dem Bildnamen ein Präfix hinzufügen.

Die meiste Zeit funktioniert es gut (das Bild wird gerendert). In einigen Fällen wird das Bild jedoch nicht angezeigt. In solchen Fällen werden der Winkel Schnipsel zu diesem HTML übersetzt (man beachte die style="display: none;" im ersten img-Tag):

<img ng-show="order.img" ng-src="http://xx.s3.amazonaws.com/o/img1.jpg" onerror="this.style.display='none'" src="http://xx.s3.amazonaws.com/o/img1.jpg" style="display: none;"> 
<img ng-hide="order.img" ng-src="http://xx.s3.amazonaws.com/default.png" class="ng-hide" src="http://xx.s3.amazonaws.com/default.png" style=""> 

Frage: Was ist der Grund dafür sein könnte? Und mögliche Problemumgehungen? Ist es, dass die onerror früher als erwartet ausgelöst wird?

PS: http://xx.s3.amazonaws.com/o/img1.jpg ist ein gültiger Bildpfad und ist verfügbar.

aktualisieren: Dies ist, wie die app/route/Controller

Strecke

t_app.config(function ($stateProvider, $urlRouterProvider, $httpProvider) { 
    // ... 
    $stateProvider.state('ref', { 
     url: '/orders/:ref', 
     templateUrl: 'views/order.htm', 
     controller: 'orderController' 
    }); 
    // ... 
}); 

-Controller definiert ist

t_app.controller('orderController', ['$scope', '$stateParams', function($scope, $stateParams) { 
     // Load the order (this step takes a while) 
}]); 
+0

Wie deklarieren Sie Ihre eckige App und Controller? Es könnte sein, dass Ihre Seite gerendert wird, bevor der Controller geladen wird. – Schokea

+0

Weitere Details hinzugefügt. Wird Ihre zweite Bemerkung dazu verwendet, 'onerror' früher oder später auszulösen? –

+0

ist die Auftragsvariable, die von einem Remote-Aufruf geladen wird? oder hat es Zwischenwerte (sagen wir "http://xx.s3.amazonaws.com/" bevor "http://xx.s3.amazonaws.com/o/img1.jpg") – valepu

Antwort

1

denke ich, was mit Ihnen geschieht ist das: http://plnkr.co/edit/8JL0Op?p=preview

angular.module('app.helper', []) 
.controller('ImgController', ['$scope', '$timeout', function($scope, $timeout) { 
    $scope.img = ""; 
    $timeout(function(){ 
    $scope.img = "9c5595db-db21-4783-902a-8e80b84ae22c/6b89ed2b-878a-4f76-95c4-76ee95f47d9a.jpg"; 
    }, 1500); 
}]); 
    filter.$inject = ["$filter"]; 
    angular.module('app.helper').filter('addPath', filter); 

    function filter($filter) { 
     function filterFn(input) { 
      return "http://cdn.playbuzz.com/cdn/"+input; 
     } 

     return filterFn; 
    } 

Der Filter addiert das Präfix vor order.img festgelegt ist, so dass die img src wird nur das Präfix (bis um lodaded wird), ohne die Bildnamen, in einem falschen src führt. Ich denke, aber ich kann nicht 100% sicher sein, der Grund, weil es nur manchmal passiert ist, dass irgendwann $scope.order geladen wird (vielleicht, wenn die Ergebnisse zwischengespeichert werden oder etwas) onerror Trigger und einige Male danach.
Es ist schwer, die Ausführungsreihenfolge zu bestimmen, wenn Sie ein neueres mischen Javascript und Winkel

Sie können dies wahrscheinlich vermeiden, indem Sie einen Scheck in Ihrem Filter hinzufügen: Wenn der Wert auf den Filter geleitet null, nicht definiert oder eine leere Zeichenfolge dann Rückkehr in diesem Fall null. So etwas wie dieses

return typeof input === "undefined" || input === null || input === "" ? null : "http://cdn.playbuzz.com/cdn/"+input; 
+0

Danke für den Zeiger, Ihr Verdacht sieht richtig aus. So sieht das HTML aus: ''. Und ja, ich war in meinem Filter nicht defensiv. Ich denke, ng-src kümmert sich darum, dass die Komponente gerendert wird, nachdem der Ausdruck ausgewertet werden kann, aber es gibt mehrere Auswertungen. Einmal wenn $ scope.order null ist und dann wenn es gefüllt wird. –

+0

Ja, wie alles, was Sie in Ihrer Ansicht verwenden, wenn Sie eckig verwenden, wird es ausgewertet, wann auch immer eckig sein Digest macht und überprüft, ob sich Werte zwischenzeitlich geändert haben. Sollten Sie Ihre order.img-Variable ändern, wird sie erneut ausgewertet und ändert die src – valepu

+0

des Bildes anders als nach leeren Werten in Ihrem Filter zu suchen (was trotzdem getan werden sollte). Sie können auch einen voreingestellten order.img-Wert auf einen transparenten Wert setzen Bild oder ein "Laden" -Bild, während Sie auf den wahren Bildpfad warten – valepu