2016-03-16 16 views
19

Obiettivo: caricare un'immagine con una fonte dinamica. Se non viene trovata alcuna immagine, caricare invece un'immagine segnaposto.Angular2: mostra l'immagine segnaposto se img src non è valido

Questo dovrebbe dimostrare quello che sto cercando di fare, ma non so come impostare validamenteImage in base a se il primo img src è valido.

<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 deve essere vero se src = "./ app/assets/images/{{}} image.ID. Jpg" restituisce un'immagine. Altrimenti restituirebbe false e solo il secondo tag img dovrebbe mostrare.

Ci sono ovvi problemi come la memorizzazione di un elenco di tutte le sorgenti di immagini valide, ma sto pensando che ci sia un modo migliore per farlo.

Qualsiasi suggerimento sul modo migliore per implementarlo in Angular2 sarebbe molto apprezzato.

+3

Guarda onerror – epascarello

risposta

56

Il modo migliore per gestire i collegamenti di immagine interrotti è l'uso della manifestazione onError per il tag <img>:

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

Una cosa da notare, assicurati che l'immagine segnaposto sia sempre in quella posizione o potresti ottenere un loop infinito penso :) – JanR

+1

Super Awesome Bro ..Grazie – Niraj

+0

Perché viene creato un ciclo? – Nofel

1
<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; 
} 
0
src="validImage ? validImageUrl : placeHolderImgUrl" 
+0

Non funziona se il risultato ritorna come richiesta errata. Deve usare la risposta di @ JanR. – kbpontius

0
Ci

è un-Angular2 non modo per puro CSS: Styling Broken Images

Ma si prega di notare le metriche di supporto del browser nell'articolo.

17

Mi sono imbattuto in un bisogno simile. Volevo impostare come predefinito un pixel trasparente 1X1 se un img url era nullo o restituiva un errore (404 ecc.).

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; 
    } 
} 
+0

Soluzione eccellente, perché src può essere nullo e in questo caso non genera un errore 404. – Liquinaut

+0

Puoi mostrare un esempio di modello usando la tua soluzione? – benek

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

E da qualche parte nella tua classe del componente:

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

grazie Tiago! sta funzionando per me. –

0

ho creato un componente personalizzato che utilizza un'immagine segnaposto se l'immagine non è ancora stato caricato o se si verifica un errore durante il caricamento IT:

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> 

quindi è possibile utilizzare le cose come:

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

PS: verifico in anticipo se l'immagine viene memorizzata nella cache per evitare l'immagine lampeggiante (normalmente quando un componente che ha l'immagine all'interno viene rifatto) tra il segnaposto e l'immagine (se è memorizzato nella cache, mostro l'immagine ancor prima che il flag caricato sia impostato su true). È possibile decommentare il registro nella funzione isCached per vedere se le immagini sono memorizzate nella cache o meno.

Problemi correlati