私が作成しているアプリケーションでは、このイメージがロードされる可能性がある前に、ユーザーが4つの情報を設定する必要があります。この画像はアプリケーションの中心部分であるため、壊れた画像リンクにより、全体が壊れているように見えます。別の画像を404に置きたいのですが。
何か案は?このためのカスタムディレクティブを作成しないようにしたいと思います。
特にドキュメントの最初の質問が同じである場合、特に同様の質問が見つからないことに驚きました。
私が作成しているアプリケーションでは、このイメージがロードされる可能性がある前に、ユーザーが4つの情報を設定する必要があります。この画像はアプリケーションの中心部分であるため、壊れた画像リンクにより、全体が壊れているように見えます。別の画像を404に置きたいのですが。
何か案は?このためのカスタムディレクティブを作成しないようにしたいと思います。
特にドキュメントの最初の質問が同じである場合、特に同様の質問が見つからないことに驚きました。
回答:
これは、画像の読み込みエラーを監視し、srcを置き換える非常に単純なディレクティブです。 (プランカー)
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
タグをグローバルに処理することでした。
ここに示さ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" />
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);
}
}
});
ng-if
、テンプレート(空のsrc文字列)で簡単にチェックできるものにウォッチを追加するのはやり過ぎです
attrs.$observe('ngSrc', function(value) {...});
$ watchの代わりにngSrcが内部的に使用するものを使用できます
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">
そのための角度や、CSSやJSは必要ありません。必要に応じて、この回答(リンクされた)を単純なディレクティブでラップして、単純化することもできますが、それは非常に単純なプロセスです...オブジェクトタグでラップするだけです...
コードでフォールバックイメージを宣言できない特定の理由はありますか?
私が理解しているように、画像ソースには2つのケースが考えられます。
これはアプリで処理する必要があると思います。現在正しいURLを特定できない場合は、代わりにloading / fallback / placeholder画像URLを渡します。
その理由は、いつでも表示する正しいURLを明示的に宣言しているため、「欠落」したイメージが決してないということです。
Angular UI Utilsの 'if statement'ディレクティブを使用して問題を解決することをお勧めします(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.showImage = value1 && value2 && value3 && value4;
ビュー内のHTML: <img ui-if="showImage" ng-src="images/{{data.value}}.jpg" />
プレースホルダー画像の場合は、別の同様の<img>
タグを追加しますが、ui-if
パラメーターの前に感嘆符(!
)マークを付け、ngSrcにプレースホルダー画像へのパスを設定するか、src
通常のHTMLのようにタグを使用します。
例えば。 <img ui-if="!showImage" src="images/placeholder.jpg" />
明らかに、上記のコードサンプルの全てが値1、値2、値3とvalue4の各々は、に等しいであろうと仮定されているnull
/ false
情報のあなたの4個のそれぞれが(のブール値にも、従って不完全である場合true
、それらが完全である場合)。
PS。AngularUIプロジェクトは最近サブプロジェクトに分割されており、のドキュメントはui-if
現在欠落しているようです(おそらくパッケージのどこかにあります)。ただし、ご覧のように使用するのは非常に簡単です。また、Angular UIプロジェクトにGithubの「問題」を記録して、チームにも指摘しました。
更新: 'ui-if'はコアAngularJSコードに統合されているため、AngularUIプロジェクトにはありません!ただし、現在「不安定」とマークされているv1.1.x以降のみ。
ng-if
それをコアbtwに作りました(私が間違っていなければ1.1.5の時点で)。
これが、ネイティブの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';
};
}
}
});
私自身の解決策を思いついた。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);
}
}
}
});
これは2回だけループすることを許可し、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);
}
});
}
}
}
})();