Wenn ein ngSrc-Pfad zu einem 404 aufgetriggers wird, gibt es eine Möglichkeit, auf einen Standard zurückzugreifen?

Bei der Anwendung, die ich erstelle, muss mein Benutzer 4 Informationen eingeben, bevor dieses Bild überhaupt geladen werden kann. Dieses Bild ist das Herzstück der Anwendung, so dass die gebrochene Bildverknüpfung es so aussehen lässt, als wäre die ganze Sache geborken. Ich möchte ein anderes Bild auf einem 404 haben.

Irgendwelche Ideen? Ich möchte vermeiden, eine benutzerdefinierte statement dafür zu schreiben.

Ich war überrascht, dass ich eine ähnliche Frage nicht finden konnte, besonders wenn die erste Frage in der Dokumentation dieselbe ist!

http://docs.angularjs.org/api/ng.directive:ngSrc

   

Es ist eine ziemlich einfache Direktive, auf einen Fehler beim Laden eines Bildes zu achten und den Quellcode zu ersetzen. (Plunker)

Html:

 

Javascript:

 var app = angular.module("MyApp", []); app.directive('errSrc', function() { return { link: function(scope, element, attrs) { element.bind('error', function() { if (attrs.src != attrs.errSrc) { attrs.$set('src', attrs.errSrc); } }); } } }); 

Wenn Sie das Fehlerbild anzeigen möchten, wenn ngSrc leer ist, können Sie Folgendes hinzufügen (Plunker) :

 attrs.$observe('ngSrc', function(value) { if (!value && attrs.errSrc) { attrs.$set('src', attrs.errSrc); } }); 

Das Problem ist, dass ngSrc das src-Attribut nicht aktualisiert, wenn der Wert leer ist.

Wenig spät zur Party, obwohl ich eine Lösung für mehr oder weniger das gleiche Problem in einem System gefunden habe, das ich baue.

Meine Idee war jedoch, JEDES Image- img Tag global zu behandeln.

Ich wollte meinen HTML err-src nicht mit überflüssigen statementen überschreiben müssen, wie etwa den hier gezeigten err-src statementen. Sehr oft, besonders bei dynamischen Bildern, werden Sie nicht wissen, ob es fehlt, bis es zu spät ist. Das Hinzufügen zusätzlicher statementen für den Fall, dass ein Bild fehlt, erscheint mir übertrieben.

Stattdessen erweitere ich das existierende img Tag, worum es bei eckigen Direktiven eigentlich geht.

Also – das ist es, was ich mir ausgedacht habe.

Hinweis : Dies erfordert, dass die vollständige JQuery-Bibliothek vorhanden ist und nicht nur JQlite Angular mit ausgeliefert wird, da wir .error()

Sie können es bei diesem Plunker in Aktion sehen

Die Direktive sieht ungefähr so ​​aus:

 app.directive('img', function () { return { restrict: 'E', link: function (scope, element, attrs) { // show an image-missing image element.error(function () { var w = element.width(); var h = element.height(); // using 20 here because it seems even a missing image will have ~18px width // after this error function has been called if (w < = 20) { w = 100; } if (h <= 20) { h = 100; } var url = 'http://placehold.it/' + w + 'x' + h + '/cccccc/ffffff&text=Oh No!'; element.prop('src', url); element.css('border', 'double 3px #cccccc'); }); } } }); 

Wenn ein Fehler auftritt (was daran liegt, dass das Bild nicht existiert oder unerreichbar ist usw.), erfassen und reagieren wir. Sie können versuchen, die Bildgrößen auch zu bekommen - wenn sie an dem Bild / Stil überhaupt vorhanden waren. Wenn nicht, dann setze dich selbst als Standard.

In diesem Beispiel wird placehold.it für ein Bild verwendet, das stattdessen angezeigt wird.

JEDES Bild, unabhängig davon, src oder ng-src ist jetzt selbst abgedeckt, falls nichts geladen wird ...

Um die Jason-Lösung so zu erweitern, dass beide Fälle eines Ladeerrorss oder einer leeren Quellzeichenfolge erfasst werden, können wir einfach eine Uhr hinzufügen.

Html:

  

Javascript:

 var app = angular.module("MyApp", []); app.directive('errSrc', function() { return { link: function(scope, element, attrs) { var watcher = scope.$watch(function() { return attrs['ngSrc']; }, function (value) { if (!value) { element.attr('src', attrs.errSrc); } }); element.bind('error', function() { element.attr('src', attrs.errSrc); }); //unsubscribe on success element.bind('load', watcher); } } }); 

Wenn Bild ist 404 oder Bild ist leer, egal was es keine Notwendigkeit für Richtlinien Sie können einfach verwenden ng-src Filter wie folgt 🙂

  
 App.directive('checkImage', function ($q) { return { restrict: 'A', link: function (scope, element, attrs) { attrs.$observe('ngSrc', function (ngSrc) { var deferred = $q.defer(); var image = new Image(); image.onerror = function () { deferred.resolve(false); element.attr('src', BASE_URL + '/assets/images/default_photo.png'); // set default image }; image.onload = function () { deferred.resolve(true); }; image.src = ngSrc; return deferred.promise; }); } }; }); 

in HTML:

  

Ich benutze so etwas, aber es geht davon aus, dass team.logo gültig ist. Es erzwingt den Standardwert, wenn “team.logo” nicht festgelegt oder leer ist.

   

Sie brauchen dafür weder eckig noch CSS oder JS. Wenn Sie möchten, können Sie diese Antwort (verlinkt) in eine einfache statement einfügen, um es einfacher oder ähnlicher zu machen, aber es ist ein ziemlich einfacher process … einfach in ein Objekt-Tag einfügen …

Wie man ein Bild mit einem gebrochenen Symbol ausblenden kann, das nur CSS / HTML verwendet (ohne js)

Gibt es einen bestimmten Grund, warum Sie das Fallback-Image nicht in Ihrem Code deklarieren können?

Wie ich es verstehe, haben Sie zwei mögliche Fälle für Ihre Bildquelle:

  1. Teile der Information richtig setzen <4 = Fallback Image.
  2. Teile der Information richtig setzen == 4 = Generierte URL.

Ich denke, dies sollte von Ihrer App gehandhabt werden – wenn die richtige URL derzeit nicht ermittelt werden kann, übergeben Sie stattdessen eine Lade- / Fallback- / Platzhalterbild-URL.

Der Grund dafür ist, dass Sie nie ein “fehlendes” Bild haben, weil Sie die korrekte URL, die zu einem beliebigen Zeitpunkt angezeigt werden soll, explizit deklariert haben.

Ich schlage vor, dass Sie die statement if-statement von Angular UI Utils verwenden möchten, um Ihr Problem zu lösen, das Sie unter http://angular-ui.github.io/ finden . Ich habe es gerade benutzt, um genau das Gleiche zu tun.

Dies ist nicht getestet, aber Sie könnten etwas tun wie:

Controller-Code:

 $scope.showImage = function () { if (value1 && value2 && value3 && value4) { return true; } else { return false; } }; 

(oder einfacher)

 $scope.showImage = function () { return value1 && value2 && value3 && value4; }; 

HTML in der Ansicht:

Oder noch einfacher: Sie könnten einfach eine scope -Eigenschaft verwenden:

Controller-Code:

 $scope.showImage = value1 && value2 && value3 && value4; 

HTML in der Ansicht:

Fügen Sie für ein Platzhalterbild einfach ein weiteres ähnliches -Tag hinzu, aber geben Sie Ihrem ui-if -Parameter ein Ausrufezeichen ( ! ) Und entweder ngSrc den Pfad zum Platzhalterbild oder verwenden Sie einfach ein src Tag wie üblich ‘HTML.

z.B.

Offensichtlich gehen alle obigen Codebeispiele davon aus, dass jedes von value1, value2, value3 und value4 mit null / false gleichgesetzt wird, wenn jede Ihrer 4 Informationen unvollständig ist (und somit auch zu einem booleschen Wert von true wenn sie vollständig sind ).

PS. Das AngularUI-Projekt wurde kürzlich in Unterprojekte eingegliedert, und die Dokumentation für ui-if scheint derzeit noch zu fehlen (wahrscheinlich liegt sie irgendwo im Paket). Es ist jedoch ziemlich einfach zu verwenden, wie Sie sehen können, und ich habe ein Github-Problem im Angular UI-Projekt protokolliert, um es auch dem Team zu zeigen.

UPDATE: ‘ui-if’ fehlt im AngularUI-Projekt, weil es in den AngularJS-Code integriert wurde! Nur ab v1.1.x, welches momentan als ‘unstable’ gekennzeichnet ist.

Hier ist eine Lösung, die ich mit nativem Javascript entwickelt habe. Ich überprüfe, ob das Bild errorshaft ist, und füge dem Bild eine class hinzu, nur für den Fall, dass ich die Quelle ändere.

Ich habe einen Teil meiner Antwort aus einer Quora-Antwort http://www.quora.com/How-do-I-use-JavaScript-to-find-if-animage-is-broken bekommen

 app.directive('imageErrorDirective', function () { return { restrict: 'A', link: function (scope, element, attrs) { element[0].onerror = function () { element[0].className = element[0].className + " image-error"; element[0].src = 'http://img3.wikia.nocookie.net/__cb20140329055736/pokemon/images/c/c9/702Dedenne.png'; }; } } }); 

Hat meine eigene Lösung gefunden. Er ersetzt das Bild, wenn src oder ngSrc leer ist und wenn img 404 zurückgibt.

(Gabel von @Darren Lösung)

 directive('img', function () { return { restrict: 'E', link: function (scope, element, attrs) { if((('ngSrc' in attrs) && typeof(attrs['ngSrc'])==='undefined') || (('src' in attrs) && typeof(attrs['src'])==='undefined')) { (function () { replaceImg(); })(); }; element.error(function () { replaceImg(); }); function replaceImg() { var w = element.width(); var h = element.height(); // using 20 here because it seems even a missing image will have ~18px width // after this error function has been called if (w < = 20) { w = 100; } if (h <= 20) { h = 100; } var url = 'http://placehold.it/' + w + 'x' + h + '/cccccc/ffffff&text=No image'; element.prop('src', url); } } } }); 

Dies erlaubt nur zweimaliges Schleifen, um zu prüfen, ob das ng-src nicht existiert, ansonsten benutze das err-src, dies verhindert die fortlaufende Schleifenbildung.

 (function () { 'use strict'; angular.module('pilierApp').directive('errSrc', errSrc); function errSrc() { return { link: function(scope, element, attrs) { element.error(function () { // to prevent looping error check if src == ngSrc if (element.prop('src')==attrs.ngSrc){ //stop loop here element.prop('src', attrs.errSrc); } }); } } } })();