简体   繁体   中英

Show Image Element only if image exists in Angular

I have two sibling elements. One is image and other is a div. I want to show image element if image exists and show div element if image doesn't exist. My elements looks like

 <img ng-show="product.img" ng-src="{{product.img}}" />
 <div class="left margin-right-1 line-height-15" ng-hide="product.img">{{product.img}}</div>

And product.img results in something like /assets/images/prod.jpg . As this is a string so ng-show will always be true and image tag will be shown. So if image doesn't exist it will show as broken image. So basically what I want is if image doesn't exist, image tag hides and div is shown and vice versa.

I have tried a javascript function like

 $scope.imageExists = function(src) {
  var image = new Image();
  image.src = src;
  if (image.width == 0) {
      return false;
  } else {
      return true;
  }
}

And changed my image tag like

 <img ng-show="product.img" ng-src="{{imageExists(product.img)}}" />

But this is very expensive. I have 100 products per page and when it loops through all images, the page becomes very very slow.

So can any body guide me what is the best way in angular to show and hide image element if image exists or not.

使用图像中的onError事件来禁用ng-show使用的变量

<img ng-show="product.img" ng-src="{{product.img}}" onError="angular.element(this).scope().product.img = false"/>

You can accomplish this using a custom directive. See Plunker: http://plnkr.co/edit/yBb0rNiXIaO4EGTqCAmm?p=preview

You'll need to attach an is404 to each of your image:

for(var i = 0; i < products.length; ++i) {
    products[i].image.is404 = false;
}

Then display them. You'll need to pass $index as an index attribute so you can use it in your directive.

<img ng-if="!image.is404" on-src-error index="{{$index}}" src="{{image.image}}" />
<div ng-if="image.is404">Uh oh!  Image 404'd.</div>

Custom directive:

app.directive("onSrcError", function() {
  return {
    link: function(scope, element, attrs) {
     element.bind('error', function() {
       //set 404 to true and apply the scope
       scope.images[attrs.index].is404 = true;
       scope.$apply();
     });
    }
  };
});

Those solutions above are good. But I suggest you put onError event logic in a directive and use ng-if to control the visibility.

 var myApp = angular.module('myApp', []) .directive('img', function() { return { restrict: 'E', scope: { ngModel: '=' }, link: function(scope, element, attrs) { element.bind('error', function() { scope.ngModel.shown = false; scope.$apply(); }); } } }) .controller('MyController', function($scope) { $scope.images = []; for (var i = 0; i < 10; i++) { if (i == 5) { $scope.images[i] = { url: 'http://www.notfound.com.fr/404.png' }; continue; } $scope.images.push({ url: 'https://unsplash.it/50/50/?random=' + i }); } }); 
 <!DOCTYPE html> <html> <head> <meta http-equiv="content-type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></script> <title></title> </head> <body ng-app="myApp" class="ng-scope"> <div ng-controller="MyController"> <div ng-repeat="image in images" ng-init="image.shown=true"> <p ng-if="!image.shown"> Empty image here... </p> <img ng-model="image" ng-if="image.shown" ng-src="{{ image.url }}"> </div> </div> </body> </html> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM