Angular2: показать изображение заполнителя, если img src недействителен

Цель. Загрузите изображение с динамическим источником. Если изображение не найдено, загрузите вместо него изображение-заполнитель.

Это должно продемонстрировать, что я пытаюсь сделать, но я не знаю, как условно установить validImage на основе того, является ли первый img src действительным.

<img *ngif="validImage" class="thumbnail-image" src="./app/assets/images/{{image.ID}}.jpg" alt="...">
<img *ngif="!validImage" class="thumbnail-image" src="./app/assets/images/placeholder.jpg" alt="...">

validImage должно быть истинным, если src= "./app/assets/images/{{image.ID}}. jpg" возвращает изображение. В противном случае он вернет false, и только второй тег img должен показать.

Есть очевидные работы, такие как сохранение списка всех допустимых источников изображений, но я думаю, что есть лучший способ добиться этого.

Любые предложения по наилучшему способу реализации этого в Angular2 были бы с благодарностью.

Ответы

Ответ 1

Лучшим способом обработки сломанных изображений является использование события onError для тега <img>:

<img  class="thumbnail-image" src="./app/assets/images/{{image.ID}}.jpg"
      onError="this.src='./app/assets/images/placeholder.jpg';"  alt="..." />

Ответ 2

Я столкнулся с аналогичной необходимостью. Я хотел по умолчанию использовать прозрачный пиксель 1X1, если img url был нулевым или возвращал ошибку (404 и т.д.).

import { Directive, Input } from '@angular/core';

@Directive({
    selector: 'img[src]',
    host: {
        '[src]': 'checkPath(src)',
        '(error)': 'onError()'
    }
})
export class DefaultImage { 
    @Input() src: string;
    public defaultImg: string = '{YOUR_DEFAULT_IMG}';
    public onError() {
        this.src = this.defaultImg;
    }
    public checkPath(src) {
        return src ? src : this.defaultImg;
    }
}

наценка

<img [src]="{DESIRED_IMAGE_SOURCE}" />

Ответ 3

<img [src]="pic" (error)="setDefaultPic()">

И где-нибудь в вашем классе компонента:

setDefaultPic() {
  this.pic = "assets/images/my-image.png";
}

Ответ 4

Я создал пользовательский компонент, который использует образ-заполнитель, если изображение все еще не загружено или если при загрузке его возникает ошибка:

img.component.ts:

import { Component, Input, OnChanges } from '@angular/core';

@Component({
    selector: 'my-img',
    templateUrl: 'img.component.html',
})
export class ImgComponent implements OnChanges {
    @Input() 
    public src: string;
    @Input() 
    public default: string;
    @Input() 
    public alt: string;
    public cached = false;
    public loaded = false;
    public error = false;

    private lastSrc: string;

    constructor() { }

    public ngOnChanges() {
        if (this.src !== this.lastSrc) {
            this.lastSrc = this.src;
            this.loaded = false;
            this.error = false;
            this.cached = this.isCached(this.src);
        }

        if (!this.src) {
            this.error = true;
        }
    }

    public onLoad() {
        this.loaded = true;
    }

    public onError() {
        this.error = true;
    }

    private isCached(url: string): boolean {
        if (!url) {
            return false;
        }

        let image = new Image();
        image.src = url;
        let complete = image.complete;

        // console.log('isCached', complete, url);

        return complete;
    }
}

img.component.html:

<ng-container *ngIf="!cached">
    <img 
        *ngIf="!error" 
        [hidden]="!loaded"
        [src]="src" 
        [alt]="alt" 
        (load)="onLoad()" 
        (error)="onError()"
    >
    <img 
        *ngIf="default && (error || !loaded)" 
        [src]="default" 
        [alt]="alt"
    >
</ng-container>

<ng-container *ngIf="cached">
    <img 
        *ngIf="!error" 
        [src]="src" 
        [alt]="alt" 
        (error)="onError()"
    >
    <img 
        *ngIf="default && error" 
        [src]="default" 
        [alt]="alt"
    >
</ng-container>

Затем вы можете использовать его как:

<my-img [src]="src" [alt]="alt" [default]="DEFAULT_IMAGE"></my-img>

PS: Я проверяю заранее, если изображение кэшируется, чтобы избежать мигания изображения (обычно, когда компонент, который имеет изображение внутри, повторно отображается) между заполнителем и изображением (если он кэширован, я показываю изображение даже до того, как установлен флаг загружен в true). Вы можете раскомментировать журнал в функции isCached, чтобы увидеть, сохранены ли ваши изображения или нет.

Ответ 5

<img class="thumbnail-image" src="getImage()" alt="...">

getImage():string{  //I don't know how would you handle your situation here. But you can think of it.

  if (this.validImage) // I don't know how would you manage validImage here.
  {
     return this.validImagePath;
  }

   return this.placeholderImagePath;
}

Ответ 6

src="validImage ? validImageUrl : placeHolderImgUrl"

Ответ 7

Существует чистый метод Angular2 с помощью чистого CSS: Укладка сломанных изображений

Но обратите внимание на показатели поддержки браузера в статье.

Ответ 8

Я просто сделал это:

В моем HTML файле написано это

<div 
   (click)="getInfo(results[movie].id)"
   *ngFor="let movie of (results | key:'10')" 
    class="card" style="margin-top:7%;">
 <img [src]="getImage(results[movie])" alt="" class="card-img-top pointer"></div>

Я вызвал функцию из моего component.ts и передал объект, где мой URL-адрес в качестве параметра

getImage(result){
if(result.poster_path){
  return this.imageURL+(result.poster_path);
}else return "./assets/noFound.jpg"

Вот моя функция, сначала я проверяю, отличается ли URL-адрес изображения объекта от нуля, если он равен true, тогда я возвращаю URL-адрес изображения, в противном случае я возвращаю изображение по умолчанию "noFound", которое находится в активах моего приложения.
Надеюсь, поможет!

Ответ 9

Следующий подход также работает, если вы хотите обработать ошибку в вашем классе:

В вашем шаблоне:

<img [src]='varWithPath' (error) ="onImgError($event)">

В вашем классе:

onImgError(event) { event.target.src= 'assets/path_to_your_placeholder_image.jpg'; }