我们可以插入一个设置了回退src
的相邻元素(img
),然后我们可以删除该指令所在的元素,这很有效!
@HostListener('error') displayFallbackImage() {
if (this.isFirstLoad) {
this.isFirstLoad = false;
var img = document.createElement('img');
img.src = this.fallbackImage;
this.renderer.appendChild(this.element.nativeElement.parentNode, img);
this.renderer.removeChild(
this.element.nativeElement.parentNode,
this.element.nativeElement,
true
);
}
}
完整代码
双手
import { Component } from '@angular/core';
import { bootstrapApplication, DomSanitizer } from '@angular/platform-browser';
import 'zone.js';
import { ImgFallbackDirective } from './test.指令';
@Component({
selector: 'app-root',
standalone: true,
imports: [ImgFallbackDirective],
template: `
<img [src]="sanitizer.bypassSecurityTrustResourceUrl(failingUrl)"
fallbackImage="https://placehold.co/600x400">
`,
})
export class App {
failingUrl = 'https://placeeeeeeeeeehold.co/600x400';
constructor(public sanitizer: DomSanitizer) {}
setFailingUrl(value: any) {
console.log(value);
this.failingUrl = value;
}
}
bootstrapApplication(App);
指令
import {
Directive,
ElementRef,
HostListener,
Input,
Renderer2,
} from '@angular/core';
@Directive({
selector: 'img[fallbackImage]',
standalone: true,
})
export class ImgFallbackDirective {
isFirstLoad = true;
constructor(private element: ElementRef, private renderer: Renderer2) {}
@Input('fallbackImage') fallbackImage!: string;
@HostListener('error') displayFallbackImage() {
if (this.isFirstLoad) {
this.isFirstLoad = false;
var img = document.createElement('img');
img.src = this.fallbackImage;
this.renderer.appendChild(this.element.nativeElement.parentNode, img);
this.renderer.removeChild(
this.element.nativeElement.parentNode,
this.element.nativeElement,
true
);
}
}
}
Stackblitz Demo