如果 ngSrc 路径解析为404,是否有方法回退到默认值?

我正在构建的应用程序要求我的用户在这个图像有机会加载之前设置4条信息。这个图像是应用程序的核心部分,因此断开的图像链接使得整个事情看起来像是被勾掉了。我想让另一张图片代替404的位置。

有什么想法吗? 我想避免为此写一个自定义指令。

我很惊讶我找不到一个类似的问题,尤其是当文档中的第一个问题是同一个问题的时候!

Http://docs.angularjs.org/api/ng.directive:ngsrc

83053 次浏览

是否有特定的原因使您不能在代码中声明回退映像?

据我所知,你的图像来源有两种可能的情况:

  1. 正确设置信息片段 < 4 = 后备图像。
  2. 正确设置信息片段 = = 4 = 生成的 URL。

我认为这应该由您的应用程序处理-如果正确的 URL 当前无法确定,而是传递一个加载/回退/占位符图像 URL。

这样做的原因是,您永远不会有“丢失”的图像,因为您已经明确声明了要在任何时间点显示的正确 URL。

我建议您可以使用 Angular UI Utils“ if 语句”指令来解决您的问题,如 http://angular-ui.github.io/所示。我刚刚用它来做完全相同的事情。

这是未经测试的,但是您可以这样做:

控制器代码:

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

(或更简单)

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

视图中的 HTML: <img ui-if="showImage()" ng-src="images/\{\{data.value}}.jpg" />

或者更简单一点,您可以只使用 scope 属性:

控制器代码:

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

视图中的 HTML: <img ui-if="showImage" ng-src="images/\{\{data.value}}.jpg" />

对于占位符图像,只需添加另一个类似的 <img>标记,但在 ui-if参数前面加上一个感叹号(!) ,并使 ngSrc 具有占位符图像的路径,或者按照普通 ol’HTML 使用 src标记。

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

显然,上面的所有代码示例都假设 value1、 value2、 value3和 value4中的每一个都等同于 null/false,当您的4个信息片段中的每一个都不完整时(因此当它们完整时也等同于一个布尔值 true)。

附言。AngularUI 项目最近被划分为子项目,目前似乎缺少 ui-if的文档(尽管它可能在包的某个地方)。然而,正如你所看到的,它的使用非常简单,我也在 Angular UI 项目中记录了一个 Github“问题”,以便向团队指出它。

更新: ‘ ui-if’在 AngularUI 项目中丢失了,因为它已经集成到 AngularJS 核心代码中了!不过只是1.1. x 版本,目前被标记为“不稳定”。

观察加载图像的错误并替换 src.(Plunker)是一个非常简单的指令

网址:

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

如果希望在 ngSrc 为空时显示错误图像,可以添加以下 (Plunker):

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

问题是,如果值为空,ngSrc 不会更新 src 属性。

要扩展 Jason 解决方案以捕获加载错误或空源字符串的两种情况,我们只需添加一个 watch。

网址:

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


}
}
});

现在有点晚了,不过我想出了一个解决方案,来解决我正在构建的系统中差不多相同的问题。

不过,我的想法是在全球范围内处理每个图像 img标签。

我不想在 HTML中添加不必要的指令,比如这里显示的 err-src指令。很多时候,尤其是动态图像,你不会知道它是否丢失,直到为时已晚。在图像丢失的可能性上添加额外的指令对我来说有点过了。

相反,我扩展了现有的 img标记——这实际上就是 Angular 指令的全部内容。

这就是我想到的。

注意 : 这需要提供完整的 JQuery 库,而不仅仅是 JQlite Angular,因为我们使用的是 .error()

你可以在这个 笨蛋上看到它的运作

这个指令看起来很像这样:

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 来显示一个图像。

现在,每个图像,无论使用 srcng-src已经覆盖本身的情况下没有加载..。

我使用类似的东西,但是它假设 Team. logo 是有效的。如果“ team. logo”未设置或为空,则强制默认设置。

<img ng-if="team.logo" ng-src="https://api.example.com/images/\{\{team.logo}}">
<img ng-hide="team.logo" ng-src="img/default.png">

如果 image 为404或 image 为 null 空,则不需要指令,您可以像这样简单地使用 ng-src 过滤器:)

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

下面是我用本地 javascript 想出的一个解决方案。我正在检查图像是否损坏,然后为图像添加一个类,以防万一,并更改源代码。

我的部分答案来自 Quora 的答案 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';
};
}
}
});
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;
});
}
};
});

超文本标示语言(HTML) :

<img class="img-circle" check-image ng-src="\{\{item.profileImg}}" />

想出了我自己的解决办法。 如果 src 或 ngSrc 为空,则替换 image,如果 img 返回404,则替换 image。

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

你不需要棱角,甚至不需要 CSS 或 JS。如果你愿意,你可以用一个简单的指令来包装这个答案(链接) ,让它变得更简单,但是这是一个非常简单的过程... 只要把它包装在一个对象标记中..。

如何隐藏图像破碎图标只使用 CSS/HTML (没有 js)

这将只允许循环两次,以检查 ng-src 是否不存在,否则使用 err-src,这将防止继续循环。

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