Estoy tratando de hacer una directiva simple. Cuando la imagen se está cargando, el img src se establecerá en un campo de cadena @Input() . Al cargar, la imagen se establecerá en el valor src original (o al menos cómo estoy tratando de implementarlo).
Estaba usando la respuesta aquí: https://stackoverflow.com/a/38837619/843443 pero no es una directiva y, por lo tanto, requeriría una serie de cambios donde sea que use imágenes.
Mi primer intento:
cargando-img.directive.ts:
import { Directive, ElementRef, HostListener, Input } from '@angular/core'; @Directive({ selector: '[tohLoadingImg]' }) export class LoadingImgDirective { imgSrc: String; @Input() spinnerSrc: String; constructor(private el: ElementRef) { this.imgSrc = el.nativeElement.src; el.nativeElement.src = this.spinnerSrc; } @HostListener('load') onLoad() { this.el.nativeElement.src = this.imgSrc; } }de:
<img src="{{hero.imgUrl}}" alt="Random first slide">a:
<img src="{{hero.imgUrl}}" alt="Random first slide" [tohLoadingImg]="'/assets/ring.svg'">Error:
Can't bind to 'tohLoadingImg' since it isn't a known property of 'img'. (".imgUrl}}" alt="Random first slide">-->¿Qué me estoy perdiendo?
Prueba esto
import { Directive, Attribute, Renderer2, ElementRef, HostListener } from '@angular/core'; @Directive({ selector: '[uiImageLoader]' }) export class UiImageLoaderDirective { constructor( @Attribute('loader') public loader: string, @Attribute('onErrorSrc') public onErrorSrc: string, private renderer: Renderer2, private el: ElementRef) { this.renderer.setAttribute(this.el.nativeElement, 'src', this.loader); } @HostListener('load') onLoad() { this.renderer.setAttribute(this.el.nativeElement, 'src', this.el.nativeElement.src); } @HostListener('error') onError() { this.renderer.setAttribute(this.el.nativeElement, 'src', this.onErrorSrc); } } <img uiImageLoader onErrorSrc="/assets/images/no-available-800.png" loader="/assets/images/image-loader.svg" [src]="post.imagePath" [alt]="post.title">Gracias a @Aravind por la dirección. Así es como lo resolví (usando un componente en lugar de una directiva):
spinner-img.component.ts:
import { Component, OnInit, Input } from '@angular/core'; @Component({ selector: 'toh-spinner-img', templateUrl: './spinner-img.component.html', styleUrls: ['./spinner-img.component.scss'] }) export class SpinnerImgComponent implements OnInit { @Input() imgSrc: String; @Input() spinnerSrc: String; @Input() imgContainerClass: String; loading: boolean = true onLoad() { this.loading = false; } constructor() { } ngOnInit() { } }spinner-img.component.html:
<div [class]="imgContainerClass"> <img *ngIf="loading" src="{{spinnerSrc}}" alt="loading"/> <img [hidden]="loading" (load)="onLoad()" src="{{imgSrc}}" alt="Hero Pic"/> </div>Y en uso:
<toh-spinner-img [imgSrc]="hero.imgUrl" [spinnerSrc]="'/assets/ring.svg'"></toh-spinner-img>