IT

ngSrc 경로가 404로 해석되면 기본값으로 대체하는 방법이 있습니까?

lottoking 2020. 7. 2. 07:26
반응형

ngSrc 경로가 404로 해석되면 기본값으로 대체하는 방법이 있습니까?


내가 만들고있는 응용 프로그램은이 이미지가로드되기 전에 사용자가 4 가지 정보를 설정해야합니다. 이 이미지는 응용 프로그램의 중심 부분이므로 이미지 링크가 끊어지면 전체가 멍한 것처럼 보입니다. 404에서 다른 이미지를 사용하고 싶습니다.

어떤 아이디어? 이에 대한 사용자 지정 지시문 작성을 피하고 싶습니다.

특히 문서의 첫 번째 질문이 같은 경우 비슷한 질문을 찾을 수 없다는 것에 놀랐습니다.

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


이미지 로딩 오류를보고 src를 교체하는 것은 매우 간단한 지시어입니다. (플 런커)

HTML :

<img ng-src="smiley.png" err-src="http://google.com/favicon.ico" />

자바 스크립트 :

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

ngSrc가 비어있을 때 오류 이미지를 표시하려면 다음을 추가하십시오 (Plunker) .

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

문제는 값이 비어 있으면 ngSrc가 src 속성을 업데이트하지 않는다는 것입니다.


파티에 조금 늦었지만, 내가 구축하는 시스템에서 거의 같은 문제에 대한 해결책을 찾았습니다.

그러나 내 생각은 모든 이미지 img태그를 전 세계적으로 처리하는 것이 었습니다 .

나는 여기에 표시된 것과 HTML같은 불필요한 지시어로 내 고추를 피우고 싶지 않았습니다 err-src. 특히 동적 이미지의 경우 너무 늦을 때까지 이미지가 누락되었는지 알 수 없습니다. 오프-기회에 추가 지시문을 추가하면 이미지가 과도하게 보입니다.

대신 기존 img태그를 확장합니다 . 실제로 Angular 지시문이 전부입니다.

그래서 이것은 내가 생각해 낸 것입니다.

참고 :이를 위해서는 JQlite Angular뿐만 아니라 전체 JQuery 라이브러리가 있어야합니다..error()

Plunker 에서 작동하는 것을 볼 수 있습니다

지시문은 다음과 같이 보입니다.

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

오류가 발생하면 (이미지가 존재하지 않거나 도달 할 수 없기 때문에) 캡처하고 반응합니다. 이미지 / 스타일에 이미지 크기가있는 경우 이미지 크기도 얻을 수 있습니다. 그렇지 않은 경우 자신을 기본값으로 설정하십시오.

이 예제는 placehold.it를 사용하여 이미지를 대신 표시합니다.

이제 모든 이미지, 사용 여부에 관계없이 src또는 ng-src아무것도로드되지 않는 경우를 대비 하여 덮었습니다 ...


Jason 솔루션을 확장하여로드 오류 또는 빈 소스 문자열의 두 경우를 모두 포착하려면 시계를 추가하면됩니다.

HTML :

<img ng-src="smiley.png" err-src="http://google.com/favicon.ico" />

자바 스크립트 :

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}}" />

If image is 404 or image is null empty whatever there is no need for directives you can simply use ng-src filter like this :)

<img ng-src="{{ p.image || 'img/no-image.png' }}" />

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

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)


Is there a specific reason you can't declare the fallback image in your code?

As I understand, you have two possible cases for your image source:

  1. Correctly set pieces of information < 4 = Fallback image.
  2. Correctly set pieces of information == 4 = Generated URL.

I think this should be handled by your app - if the correct URL cannot currently be determined, instead pass a loading/fallback/placeholder image URL.

The reasoning is that you never have a 'missing' image, because you have explicitly declared the correct URL to display at any point in time.


I suggest that you might like to use the Angular UI Utils 'if statement' directive to solve your problem, as found at http://angular-ui.github.io/. I have just used it to do exactly the same thing.

This is untested, but you could do something like:

Controller code:

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

(or simpler)

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

HTML in View: <img ui-if="showImage()" ng-src="images/{{data.value}}.jpg" />

Or even simpler, you could just use a scope property:

Controller code:

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

HTML in View: <img ui-if="showImage" ng-src="images/{{data.value}}.jpg" />

For a placeholder image, just add another similar <img> tag but prepend your ui-if parameter with an exclamation (!) mark, and either make ngSrc have the path to the placeholder image, or just use a src tag as per normal ol' HTML.

eg. <img ui-if="!showImage" src="images/placeholder.jpg" />

Obviously, all of the above code samples are assuming that each of value1, value2, value3 and value4 will equate to null / false when each of your 4 pieces of information are incomplete (and thus also to a boolean value of true when they are complete).

PS. The AngularUI project has recently been broken in to sub-projects, and the documentation for ui-if seems to be missing currently (it's probably in the package somewhere though). However, it is pretty straightforward to use as you can see, and I have logged a Github 'issue' on the Angular UI project to point it out to the team too.

UPDATE: 'ui-if' is missing from the AngularUI project because it's been integrated in to the core AngularJS code! Only as of v1.1.x though, which is currently marked as 'unstable'.


Here's a solution I came up with using native javascript. I'm checking if the image is broken then adding a class to the image just in case and changing the source.

I got part of my answer from a Quora answer http://www.quora.com/How-do-I-use-JavaScript-to-find-if-an-image-is-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';
            };
        }
    }
});

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

This will allow only to loop twice, to check if the ng-src doesn't exist else use the err-src, this prevents the continues looping.

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

참고URL : https://stackoverflow.com/questions/16310298/if-a-ngsrc-path-resolves-to-a-404-is-there-a-way-to-fallback-to-a-default

반응형