Für die Anwendung, die ich baue, muss mein Benutzer 4 Informationen festlegen, bevor dieses Image überhaupt geladen werden kann. Dieses Bild ist das Herzstück der Anwendung, so dass die Verknüpfung mit dem defekten Bild so aussieht, als wäre das Ganze verzerrt. Ich hätte gerne, dass ein anderes Bild auf einer 404 erscheint.
Irgendwelche Ideen? Ich möchte vermeiden, dafür eine benutzerdefinierte Direktive zu schreiben.
Ich war überrascht, dass ich keine ähnliche Frage finden konnte, vor allem wenn die erste Frage in den Dokumenten dieselbe ist!
Es ist eine ziemlich einfache Anweisung, auf Fehler beim Laden eines Bildes zu achten und die src zu ersetzen. (Plunker)
Html:
<img ng-src="smiley.png" err-src="http://google.com/favicon.ico" />
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 dieses (Plunker) hinzufügen:
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.
Etwas 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 Bild img
-Tag global zu behandeln.
Ich wollte meine HTML
nicht mit unnötigen Anweisungen, wie den hier gezeigten err-src
, pfeffern. Sehr oft, besonders bei dynamischen Bildern, wissen Sie erst dann, wenn es fehlt, wenn es zu spät ist. Das Hinzufügen zusätzlicher Anweisungen für das Off-Chance-Fehlen eines Bildes erscheint mir übertrieben.
Stattdessen erweitere ich das vorhandene img
-Tag - um genau das geht es bei den Angular-Direktiven.
Also, das ist was ich mir ausgedacht habe.
Note: Dies setzt voraus, dass die gesamte JQuery-Bibliothek vorhanden ist und nicht nur die JQlite Angular-Schiffe, da wir .error()
verwenden.
Sie können es in Aktion an diesem Plunker 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 darauf zurückzuführen ist, dass das Bild nicht existiert oder nicht erreichbar ist usw.), erfassen und reagieren wir. Sie können auch versuchen, die Bildgröße zu ermitteln - wenn sie überhaupt auf dem Bild/Stil vorhanden waren. Wenn nicht, dann setzen Sie sich als Standard.
In diesem Beispiel wird stattdessen placehold.it für ein Bild verwendet.
Nun hat sich JEDES Bild, unabhängig von src
oder ng-src
, selbst gedeckt, falls nichts geladen wird ...
Um die Jason-Lösung zu erweitern, um beide Fälle eines Ladefehlers oder eine leere Quellzeichenfolge abzufangen, können Sie einfach eine Uhr hinzufügen.
Html:
<img ng-src="smiley.png" err-src="http://google.com/favicon.ico" />
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);
}
}
});
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:
<img class="img-circle" check-image ng-src="{{item.profileImg}}" />
Wenn das Bild 404 ist oder das Bild leer ist, können Sie den ng-src-Filter einfach wie folgt verwenden:
<img ng-src="{{ p.image || 'img/no-image.png' }}" />
Ich benutze so etwas, aber es setzt voraus, dass team.logo gültig ist. Es erzwingt die Standardeinstellung, wenn "team.logo" nicht festgelegt oder leer ist.
<img ng-if="team.logo" ng-src="https://api.example.com/images/{{team.logo}}">
<img ng-hide="team.logo" ng-src="img/default.png">
Dafür brauchen Sie kein eckig oder CSS oder JS. Wenn Sie möchten, können Sie diese Antwort (verknüpft) in eine einfache Direktive einhüllen, um sie einfacher oder ähnlicher zu machen. Dies ist jedoch ein ziemlich einfacher Prozess.
So blenden Sie ein Symbol mit gebrochenem Bild nur mit CSS/HTML (ohne js) aus
Hier ist eine Lösung, die ich mit nativem Javascript gefunden habe. Ich überprüfe, ob das Bild beschädigt ist, und füge dem Bild eine Klasse hinzu, nur für den Fall, und die Quelle ändern.
Ich habe einen Teil meiner Antwort aus einer Antwort von Quora erhalten http://www.quora.com/How-do-I-use-JavaScript-to-find-if-an-imimage-isbroken
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';
};
}
}
});
Gibt es einen bestimmten Grund, aus dem Sie das Fallback-Bild nicht in Ihrem Code deklarieren können?
Soweit ich weiß, haben Sie zwei mögliche Fälle für Ihre Bildquelle:
Ich denke, dass dies von Ihrer App gehandhabt werden sollte - falls die korrekte URL derzeit nicht ermittelt werden kann, geben Sie stattdessen eine Lade-/Fallback-/Platzhalter-Image-URL an.
Der Grund ist, dass Sie niemals ein "fehlendes" Bild haben, weil Sie explizit die korrekte URL für die Anzeige zu einem bestimmten Zeitpunkt erklärt haben.
Ich schlage vor, dass Sie die if-Anweisung von Angular UI Utils verwenden möchten, um Ihr Problem zu lösen, wie unter http://angular-ui.github.io/ zu finden. Ich habe es gerade benutzt, um genau dasselbe zu tun.
Dies ist nicht getestet, aber Sie könnten so etwas tun:
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 View: <img ui-if="showImage()" ng-src="images/{{data.value}}.jpg" />
Oder noch einfacher: Sie können einfach eine Bereichseigenschaft verwenden:
Controller-Code:
$scope.showImage = value1 && value2 && value3 && value4;
HTML in View: <img ui-if="showImage" ng-src="images/{{data.value}}.jpg" />
Fügen Sie für ein Platzhalterbild einfach ein weiteres ähnliches <img>
-Tag hinzu, wobei Sie dem ui-if
-Parameter ein Ausrufezeichen (!
) voranstellen und entweder ngSrc den Pfad zum Platzhalterbild angeben oder einfach ein src
-Tag wie im normalen HTML verwenden.
z.B. <img ui-if="!showImage" src="images/placeholder.jpg" />
Offensichtlich gehen alle obigen Codebeispiele davon aus, dass Wert1, Wert2, Wert3 und Wert4 jeweils null
/false
entsprechen, wenn jede Ihrer 4 Informationen unvollständig ist (und somit auch einen booleschen Wert von true
, wenn sie vollständig sind ).
PS. Das AngularUI-Projekt wurde kürzlich in Unterprojekte eingebrochen, und die Dokumentation für ui-if
scheint derzeit zu fehlen (sie befindet sich wahrscheinlich irgendwo im Paket). Es ist jedoch ziemlich einfach zu verwenden, wie Sie sehen können, und ich habe ein Problem von Github im Angular UI-Projekt protokolliert, um es auch dem Team anzuzeigen.
UPDATE: 'ui-if' fehlt im AngularUI-Projekt, da es in den Kerncode von AngularJS integriert ist! Allerdings erst ab v1.1.x, das derzeit als "unstable" markiert ist.
Ist mit meiner eigenen Lösung aufgetaucht .. _. Sie ersetzt image, wenn src oder ngSrc leer ist und 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 eine zweimalige Schleife, um zu überprüfen, ob ng-src nicht vorhanden ist. Andernfalls verwenden Sie err-src. Dadurch wird die weitere Schleife verhindert.
(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);
}
});
}
}
}
})();