it-swarm.com.de

wenn ein ngSrc-Pfad in 404 aufgelöst wird, gibt es eine Möglichkeit, auf einen Standardwert zurückzugreifen?

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!

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

129
will_hardin

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.

251
Jason Goemaat

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 ...

48
Darren

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

    }
  }
});
21
user2899845
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}}" />
10
Mehul

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' }}" />
10
NeoNe

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">
8
evandentremont

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

2
Nick Steele

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';
            };
        }
    }
});
1
Anselm Marie

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:

  1. Richtig gesetzte Informationen <4 = Fallback-Bild.
  2. Richtig gesetzte Informationen = 4 = generierte URL.

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.

1
Alex Osborn

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.

1
Matty J

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);
        }
    }
}
});
0
andrfas

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);
                }              
            });
            }
        }
    }
})();
0