作成しているアプリケーションでは、このイメージがロードされる前に、ユーザーが4つの情報を設定する必要があります。この画像はアプリケーションの中心部分であるため、画像リンクが壊れているため、全体が途切れているように見えます。 404に別の画像を置きたいのですが。
何か案は?このためのカスタムディレクティブを記述しないようにします。
特にドキュメントの最初の質問が同じものである場合、同様の質問が見つからなかったことに驚きました!
これは、画像の読み込みエラーを監視し、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);
}
});
}
}
});
NgSrcが空白のときにエラー画像を表示したい場合は、これを追加できます (Plunker) :
attrs.$observe('ngSrc', function(value) {
if (!value && attrs.errSrc) {
attrs.$set('src', attrs.errSrc);
}
});
問題は、値が空白の場合、ngSrcはsrc属性を更新しないことです。
パーティーに少し遅れましたが、私が構築しているシステムで多かれ少なかれ同じ問題の解決策を思いつきました。
しかし、私の考えは、すべての画像img
タグをグローバルに処理することでした。
ここに示されているerr-src
のような不要なディレクティブでHTML
をペッパー化する必要はありませんでした。かなり頻繁に、特に動的画像の場合、手遅れになるまでそれが欠落しているかどうかはわかりません。画像が欠落している偶然に余分なディレクティブを追加すると、私にはやり過ぎのように思えます。
代わりに、既存のimg
タグを拡張します。これは、実際にはAngularディレクティブの目的です。
だから-これは私が思いついたものです。
注:これには、.error()
を使用しているため、付属のJQlite Angularだけでなく、完全なJQueryライブラリが必要です。
あなたはこれで実際にそれを見ることができます 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" />
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);
}
}
});
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}}" />
画像が404の場合、またはディレクティブが不要な場合は画像がnull空の場合、次のようにng-srcフィルタを使用できます:)
<img ng-src="{{ p.image || 'img/no-image.png' }}" />
私はこのようなものを使用しますが、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">
そのためにangularも、CSSやJSも必要ありません。必要に応じて、この回答(リンク)をシンプルなディレクティブでラップして、よりシンプルにすることができます。
ネイティブ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';
};
}
}
});
コードでフォールバックイメージを宣言できない特別な理由はありますか?
私が理解しているように、あなたはあなたの画像ソースに対して2つの可能なケースを持っています:
これはアプリで処理する必要があると思います-正しいURLを現在判別できない場合は、代わりにロード/フォールバック/プレースホルダーイメージURLを渡します。
理由は、いつでも表示する正しいURLを明示的に宣言しているため、「失われた」画像がないことです。
http://angular-ui.github.io/ にあるように、Angular UI Utils 'if statement'ディレクティブを使用して問題を解決することをお勧めします。 。まったく同じことをするために使用しました。
これはテストされていませんが、次のようなことができます。
コントローラーコード:
$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.showImage = value1 && value2 && value3 && value4;
ビューのHTML:<img ui-if="showImage" ng-src="images/{{data.value}}.jpg" />
プレースホルダーイメージの場合は、別の同様の<img>
タグを追加しますが、ui-if
パラメーターに感嘆符(!
)マークを付加し、ngSrcにプレースホルダーイメージへのパスを設定するか、通常のol 'HTMLに従ってsrc
name__タグを使用します。
例えば。 <img ui-if="!showImage" src="images/placeholder.jpg" />
明らかに、上記のコードサンプルはすべて、value1、value2、value3、およびvalue4のそれぞれが、4つの情報のそれぞれが不完全なときにnull
name__/false
name__と等しくなることを前提としています(したがって、ブール値がtrue
name__になると仮定します) )。
PS。 AngularUIプロジェクトは最近サブプロジェクトに分割され、ui-if
のドキュメントは現在欠落しているようです(おそらくパッケージのどこかにあります)。ただし、ご覧のとおり使用するのは非常に簡単で、Angular UIプロジェクトにGithubの「問題」を記録して、チームにも指摘しています。
更新: 'ui-if'は、AngularJSコードに統合されているため、AngularUIプロジェクトにありません!ただし、現在「不安定」とマークされているv1.1.xのみ。
私自身の解決策を思いついた。 srcまたはngSrcが空の場合、およびimgが404を返す場合の両方で画像を置き換えます。
(@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);
}
}
}
});
これにより、ng-srcが存在しないかどうかを確認するために2回だけループできます。そうでない場合は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);
}
});
}
}
}
})();