se um caminho ngSrc for resolvido para um 404, existe uma maneira de retornar a um padrão?

O aplicativo que estou criando exige que meu usuário defina quatro informações antes que essa imagem tenha a chance de ser carregada. Essa imagem é a peça central do aplicativo, portanto, o link da imagem quebrada faz com que pareça que a coisa toda está borkeada. Eu gostaria de ter outra imagem tomando seu lugar em um 404.

Alguma ideia? Eu gostaria de evitar escrever uma diretiva personalizada para isso.

Fiquei surpreso por não conseguir encontrar uma pergunta semelhante, especialmente quando a primeira pergunta nos documentos é a mesma!

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

É uma diretiva bem simples de se observar um erro ao carregar uma imagem e replace o src. (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); } }); } } }); 

Se você quiser exibir a imagem de erro quando ngSrc estiver em branco, você pode adicionar isto (Plunker) :

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

O problema é que o ngSrc não atualiza o atributo src se o valor estiver em branco.

Pouco atrasado para a festa, embora eu tenha encontrado uma solução para mais ou menos o mesmo problema em um sistema que estou construindo.

Minha ideia era, no entanto, lidar com TODAS as imagens img tag globalmente.

Eu não queria ter que apimentar meu HTML com diretivas desnecessárias, como as err-src mostradas aqui. Muitas vezes, especialmente com imagens dinâmicas, você não saberá se está faltando até que seja tarde demais. Adicionando diretivas extras sobre a chance de uma imagem está faltando parece um exagero para mim.

Em vez disso, eu estendo a tag img existente – o que, na verdade, é o que as diretivas angulares são.

Então – é isso que eu criei.

Nota : Isso requer que a biblioteca completa do JQuery esteja presente e não apenas as naves do JQlite Angular porque estamos usando .error()

Você pode vê-lo em ação neste Plunker

A diretiva parece muito com isso:

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

Quando ocorre um erro (que será porque a imagem não existe ou é inacessível, etc.), capturamos e reagimos. Você pode tentar obter os tamanhos das imagens também - se eles estivessem presentes na imagem / estilo em primeiro lugar. Se não, defina-se como padrão.

Este exemplo está usando placehold.it para uma imagem para mostrar.

Agora TODAS as imagens, independentemente do uso de src ou ng-src , já foram cobertas, caso nada seja carregado ...

Para expandir a solução do Jason para capturar os dois casos de erro de carregamento ou uma string de origem vazia, podemos adicionar um relógio.

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

Se a imagem é 404 ou a imagem é nula vazia o que não há necessidade de diretivas você pode simplesmente usar o filtro ng-src como este 🙂

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

em HTML:

  

Eu uso algo assim, mas assume que time.logo é válido. Ele força o padrão se “team.logo” não estiver definido ou estiver vazio.

   

Você não precisa de um ângulo para isso, ou mesmo CSS ou JS. Se você quiser, pode envolver essa resposta (vinculada) em uma simples diretiva para torná-la mais simples, como ou algo assim, mas é um processo bem simples … basta envolvê-la em uma tag de object …

Como esconder a imagem quebrada Ícone usando apenas CSS / HTML (sem js)

Existe um motivo específico pelo qual você não pode declarar a imagem substituta em seu código?

Pelo que entendi, você tem dois casos possíveis para a sua fonte de imagem:

  1. Definir corretamente as informações <4 = Fallback image.
  2. Definir corretamente as informações = = 4 = URL gerado.

Acho que isso deve ser tratado pelo seu aplicativo. Se o URL correto não puder ser determinado no momento, passe um URL de imagem de carregamento / reserva / espaço reservado.

O raciocínio é que você nunca tem uma imagem ‘ausente’, porque você declarou explicitamente o URL correto para exibir a qualquer momento.

Sugiro que você queira usar a diretiva “if statement” do Angular UI Utils para resolver seu problema, conforme encontrado em http://angular-ui.github.io/ . Acabei de usá-lo para fazer exatamente a mesma coisa.

Isso não foi testado, mas você poderia fazer algo como:

Código do controlador:

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

(ou mais simples)

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

HTML na Visualização:

Ou ainda mais simples, você poderia simplesmente usar uma propriedade de escopo:

Código do controlador:

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

HTML na Visualização:

Para uma imagem de espaço reservado, basta adicionar outra tag semelhante, mas prefixar seu parâmetro ui-if com uma marca de exclamação ( ! ) E fazer ngSrc ter o caminho para a imagem de espaço reservado ou apenas usar uma tag src HTML.

por exemplo.

Obviamente, todas as amostras de código acima estão assumindo que cada um dos valores1, valor2, valor3 e valor4 será igual a null / false quando cada uma das suas 4 partes de informações estiver incompleta (e, portanto, também para um valor booleano true quando elas estiverem completas ).

PS. O projeto AngularUI foi recentemente dividido em subprojetos, e a documentação para o ui-if parece estar faltando atualmente (provavelmente está no pacote em algum lugar). No entanto, é bastante simples de usar, como você pode ver, e eu registrei um ‘problema’ no Github no projeto de interface do usuário angular para apontá-lo para a equipe também.

ATUALIZAÇÃO: ‘ui-if’ está faltando no projeto AngularUI porque ele foi integrado ao código central do AngularJS! Apenas a partir de v1.1.x, que atualmente está marcada como ‘instável’.

Aqui está uma solução que eu criei usando javascript nativo. Eu estou verificando se a imagem está quebrada, em seguida, adicionando uma class para a imagem apenas no caso e alterando a fonte.

Eu recebi parte da minha resposta de uma resposta do Quora http://www.quora.com/How-do-I-use-JavaScript-para-encontrar-se-uma-imagem-e-broken

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

Veio com minha própria solução. Ele substitui a imagem se src ou ngSrc estiver vazio e se img retornar 404.

(garfo da solução @Darren)

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

Isso permitirá apenas fazer um loop duas vezes, para verificar se o ng-src não existe mais use o err-src, isso evita que continue o loop.

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