web-dev-qa-db-fra.com

Angular2: Afficher l'image de marque de réservation si img src n'est pas valide

Objectif : Charge une image avec une source dynamique. Si aucune image n'est trouvée, chargez une image d'espace réservé à la place.

Cela devrait montrer ce que j'essaie de faire, mais je ne sais pas comment définir de manière conditionnelle validImage en fonction de la validité de la première 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 doit être vrai si src = "./ app/assets/images/{{image.ID}}. jpg" renvoie une image. Sinon, il renverrait false et seule la deuxième balise img devrait apparaître.

Il existe des solutions évidentes, telles que le stockage d'une liste de toutes les sources d'images valides, mais je pense qu'il existe un meilleur moyen d'y parvenir. 

Toute suggestion sur la meilleure façon de mettre en œuvre cela dans Angular2 serait grandement appréciée.

32
user2263572

Le meilleur moyen de gérer les liens d'image brisés est d'utiliser l'événement onError pour la balise <img>:

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

J'ai rencontré un besoin similaire. Je voulais utiliser par défaut un pixel transparent 1X1 si une URL d'img était nulle ou renvoyait une erreur (404, etc.).

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() {
        return this.defaultImg;
    }
    public checkPath(src) {
        return src ? src : this.defaultImg;
    }
}
20
Chris Wheaton
<img [src]="pic" (error)="setDefaultPic()">

Et quelque part dans votre classe de composant:

setDefaultPic() {
  this.pic = "assets/images/my-image.png";
}
17
Tiago Bértolo

J'ai créé un composant personnalisé qui utilise une image d'espace réservé si l'image n'est toujours pas chargée ou si une erreur se produit lors du chargement:

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>

Ensuite, vous pouvez l'utiliser comme:

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

PS: Je vérifie au préalable si l'image est mise en cache pour éviter que l'image ne clignote (normalement lorsqu'un composant contenant l'image est restituée) entre l'espace réservé et l'image (si elle est mise en cache, je montre l'image avant même le drapeau chargé doit être mis à true). Vous pouvez supprimer le commentaire du journal dans la fonction isCached pour voir si vos images sont mises en cache ou non.

2
Lucas Basquerotto
<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;
}
1
micronyks

Il existe un moyen non-angulaire2 en CSS pur: Styling Broken Images

Cependant, veuillez noter les métriques de prise en charge du navigateur dans l'article.

0
Vivien Hung
src="validImage ? validImageUrl : placeHolderImgUrl"
0
robert king

Je viens de faire ceci:

Dans mon fichier HTML écrit ceci

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

J'ai appelé une fonction qui se trouve dans mon composant.ts et transmettre l'objet à mon adresse URL en tant que paramètre

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

Voici ma fonction, je vérifie d’abord si l’URL de l’image objet est différente de NULL si elle est vraie, puis je retourne l’URL de l’image, sinon je retourne mon image "noFound" par défaut qui figure dans mes actifs d’application .
J'espère que ça aide!

0