if a ngSrc path resolves to a 404, is there a way

2019-01-04 06:20发布

The application I'm building requires my user to set 4 pieces of information before this image even has a chance of loading. This image is the center-piece of the application, so the broken image link makes it look like the whole thing is borked. I'd like to have another image take its place on a 404.

Any ideas? I'd like to avoid writing a custom directive for this.

I was surprised that I couldn't find a similar question, especially when the first question in the docs is the same one!

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

12条回答
别忘想泡老子
2楼-- · 2019-01-04 06:23

It's a pretty simple directive to watch for an error loading an image and to replace the src. (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);
        }
      });
    }
  }
});

If you want to display the error image when ngSrc is blank you can add this (Plunker):

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

The problem is that ngSrc doesn't update the src attribute if the value is blank.

查看更多
再贱就再见
3楼-- · 2019-01-04 06:27

I use something like this, but it assumes that team.logo is valid. It forces default if "team.logo" isn't set or is empty.

<img ng-if="team.logo" ng-src="https://api.example.com/images/{{team.logo}}">
<img ng-hide="team.logo" ng-src="img/default.png">
查看更多
倾城 Initia
4楼-- · 2019-01-04 06:29

Came up with my own solution. It replaces image both if src or ngSrc is empty, and if img returns 404.

(fork of @Darren solution)

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);
        }
    }
}
});
查看更多
你好瞎i
5楼-- · 2019-01-04 06:30

To expand Jason solution to catch both cases of a loading error or an empty source string, we can just add a watch.

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

    }
  }
});
查看更多
我命由我不由天
6楼-- · 2019-01-04 06:33

You don't need angular for that, or even CSS or JS. If you want, you can wrap this answer (linked) in a simple directive to make it simpler, like or something, but it's a pretty simple process... just wrap it in an object tag...

How to hide image broken Icon using only CSS/HTML (without js)

查看更多
Animai°情兽
7楼-- · 2019-01-04 06:35
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}}" />
查看更多
登录 后发表回答