TL;DR
- imgタグが壊れた時のエラーハンドルをngOnを使用する
環境
- AngularJS 1.7.9(ドキュメント見ると、1.7以上から)
imgタグが壊れた時、ngOnなしの場合
userIdを渡せば、ユーザー画像を表示するようなコンポーネントがあるとします
例えば、アカウント削除でuserIdが返ってこないとか、オフラインとか何らかの理由でリクエストが失敗すると
このような代替画像を表示させるはずです
↓
imgタグのsrcにセットした画像が取得できない場合、
・テンプレート側で壊れた画像を補う
・CSS側で補う
・JSで補う
など、特にベストプラクティスとかありそうもないので、特段の理由なくコントローラーでエラーハンドルしてました
html側でimgタグのonerror
も試したりしましたが、
答えが出なかったので、パッと見て何したいかかわかるコードで対応してました・・・
(new imageしてインスタンス作るまでするか?とか葛藤はありましたが)
しかし問題点
AngularのライフサイクルかJSにうまく乗れておらず、下記のような↓一瞬壊れた画像が表示されたあとで、代替画像が表示されていました、一瞬だったので目をつむっていました・・・
ngOnを使って克服
AngularJS1.7以上から実装されたngOnで下記のように変更しました
img.user-image(ng-on-error="ctrl.onError()" ng-src="{{ ctrl.userImageUrl }}" alt="ユーザー画像")
const noPhoto = require('_Images/no-photo.jpg');
class UserImageComponent {
private userId: string; //bindings
private userImageUrl: string; //view bind
$onChanges = changes => {
if (!changes.userId.currentValue) return;
const url = `https://hoge/thumbnail/${this.userId}.jpg`;
this.userImageUrl = url;
};
onError = () => {
this.userImageUrl = noPhoto;
};
}
export const userImage = {
template: require('./user-image.pug'),
controllerAs: 'ctrl',
controller: UserImageComponent,
bindings: {
userId: '<',
},
};
ポイント
- テンプレート側で
ng-on-error
をカスタム属性で付与し、imgタグが壊れた時にonError
が発動するように変更 - onErrorで代替画像に差し替える
だけ
これで圧倒的に直感的になり、画像も壊れたのが表示されなくなりました
Angularにも同様のやつあるんですかね?
参考
あとがき
$onInit
時に、userIdがundefindで渡ってくるときがあるので、$onChanges
を使っています