Angular2:如果img src无效,则显示占位符图像

时间:2022-06-07 12:07:08

Goal: Load an image with a dynamic source. If no image is found, then load a placeholder image instead.

目标:使用动态源加载图像。如果未找到图像,则改为加载占位符图像。

This should demonstrate what I'm trying to do, but I don't know how to conditionally set validImage based on whether the first img src is valid.

这应该展示我正在尝试做什么,但我不知道如何根据第一个img src是否有效来有条件地设置validImage。

<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 should be true if src="./app/assets/images/{{image.ID}}.jpg" returns an image. Otherwise it would return false and only the second img tag should show.

如果src =“./ app / assets / images / {{image.ID}},则validImage应该为true.jpg”返回图像。否则它将返回false并且只显示第二个img标记。

There are obvious work arounds like storing a list of all valid image sources, but I'm thinking there is a better way to accomplish this.

有明显的工作方法,比如存储所有有效图像源的列表,但我认为有更好的方法可以实现这一点。

Any suggestions on the best way to implement this in Angular2 would be greatly appreciated.

关于在Angular2中实现此方法的最佳方法的任何建议将不胜感激。

8 个解决方案

#1


83  

The best way to handle broken image links is the use the onError event for the <img> tag:

处理损坏的图像链接的最佳方法是使用Angular2:如果img src无效,则显示占位符图像标记的onError事件:

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

#2


21  

I ran into a similar need. I wanted to default to a 1X1 transparent pixel if an img url was null or returned an error (404 etc).

我遇到了类似的需求。如果img url为null或返回错误(404等),我想默认为1X1透明像素。

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

#3


13  

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

And somewhere in your component class:

在组件类的某个地方:

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

#4


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

#5


0  

src="validImage ? validImageUrl : placeHolderImgUrl"

#6


0  

There is a non-Angular2 way by pure CSS: Styling Broken Images

纯CSS有一种非Angular2方式:Styling Broken Images

But please note the browser support metrics in the article.

但请注意文章中的浏览器支持指标。

#7


0  

I've created a custom component that uses a placeholder image if the image is still not loaded or if an error occurs when loading 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>

Then you can use it like:

然后你就可以使用它:

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

PS: I verify beforehand if the image is cached to avoid the image blinking (normally when a component that has the image inside is re-rendered) between the placeholder and the image (if it is cached, I show the image even before the loaded flag be set to true). You can uncomment the log in the isCached function to see if your images are cached or not.

PS:我事先验证图像是否被高速缓存以避免图像闪烁(通常是当内部图像重新渲染的组件重新渲染时)占位符和图像之间(如果它被缓存,我甚至会在加载之前显示图像flag设置为true)。您可以取消注释isCached函数中的日志,以查看您的图像是否已缓存。

#8


0  

I Just did this :

我这样做了:

In my HTML FILE wrote this

在我的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>

I called a function that is in my component.ts and pass the object wheres my url as a parameter

我调用了一个在我的component.ts中的函数,并将该对象作为参数传递给我的url

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

Heres my function , first I verify if the object image url is different from null if is true then I return the image url else i return my default "noFound" image that is in my app assets.
Hope it helps!

继承我的功能,首先我验证对象图像url是否与null不同如果为true则返回图像url否则我返回我的app资产中的默认“noFound”图像。希望能帮助到你!

#1


83  

The best way to handle broken image links is the use the onError event for the <img> tag:

处理损坏的图像链接的最佳方法是使用Angular2:如果img src无效,则显示占位符图像标记的onError事件:

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

#2


21  

I ran into a similar need. I wanted to default to a 1X1 transparent pixel if an img url was null or returned an error (404 etc).

我遇到了类似的需求。如果img url为null或返回错误(404等),我想默认为1X1透明像素。

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

#3


13  

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

And somewhere in your component class:

在组件类的某个地方:

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

#4


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

#5


0  

src="validImage ? validImageUrl : placeHolderImgUrl"

#6


0  

There is a non-Angular2 way by pure CSS: Styling Broken Images

纯CSS有一种非Angular2方式:Styling Broken Images

But please note the browser support metrics in the article.

但请注意文章中的浏览器支持指标。

#7


0  

I've created a custom component that uses a placeholder image if the image is still not loaded or if an error occurs when loading 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>

Then you can use it like:

然后你就可以使用它:

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

PS: I verify beforehand if the image is cached to avoid the image blinking (normally when a component that has the image inside is re-rendered) between the placeholder and the image (if it is cached, I show the image even before the loaded flag be set to true). You can uncomment the log in the isCached function to see if your images are cached or not.

PS:我事先验证图像是否被高速缓存以避免图像闪烁(通常是当内部图像重新渲染的组件重新渲染时)占位符和图像之间(如果它被缓存,我甚至会在加载之前显示图像flag设置为true)。您可以取消注释isCached函数中的日志,以查看您的图像是否已缓存。

#8


0  

I Just did this :

我这样做了:

In my HTML FILE wrote this

在我的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>

I called a function that is in my component.ts and pass the object wheres my url as a parameter

我调用了一个在我的component.ts中的函数,并将该对象作为参数传递给我的url

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

Heres my function , first I verify if the object image url is different from null if is true then I return the image url else i return my default "noFound" image that is in my app assets.
Hope it helps!

继承我的功能,首先我验证对象图像url是否与null不同如果为true则返回图像url否则我返回我的app资产中的默认“noFound”图像。希望能帮助到你!