从Angular Directive访问img标记中的“ src”属性

时间:2019-07-15 08:52:45

标签: javascript angular

我正在尝试创建一个Angular指令(属性类型),当在img标签中设置该指令时,该指令用于通过占位符(即:加载微调器)替换当前的src,并且当图像正确时加载后,再次将其放回src属性以正确显示它。

这是我当前拥有的代码:

import { Directive, ElementRef, HostListener, Renderer, OnInit } from '@angular/core';

@Directive({
    selector: '[imgAsyncLoader]'
})
export class ImgAsyncLoader implements OnInit {


    imageSrc;
    element;

    constructor(el: ElementRef) {
        this.element = el;
    }

    ngOnInit(): void {
        this.imageSrc = this.element.nativeElement.src;
        console.log("original src: ", this.imageSrc)
        this.element.nativeElement.src = "assets/loading.gif";
    }

    // Trigger when image has been correctly loaded
    @HostListener('load') load() {
        console.log("img loaded")
        this.element.src = this.imageSrc;
    }
}
  1. 该指令会初始化ngOnInit钩子,并将传入的src保存在“ imageSrc”变量中。
  2. 在加载初始src时,在src中设置加载微调gif。
  3. 触发“ load”事件后,将src设置回原始事件。

我不确定这种方法是否可行,因为我不知道更改ngOnInit钩子中的src是否会取消原始资产负载,但是在更深入研究之前,我必须解决另一个问题:尝试提取图像的src的ngOnInit上的console.log无法正常工作。另外,“ setAttribute”方法未正确设置新源。  它始终显示“未定义”。

为什么我不能访问nativeElement的“ src”属性? Angular在这里有什么限制吗,或者我做错了什么?

谢谢!

编辑:

使用选定的答案后(谢谢!),我发现实现此功能的方式存在一些问题:它运行缓慢,处理过多的事件侦听器,并且在样式和性能方面均引起很多问题。这种方法在所有情况下都好得多,所以我真的建议删除@HostListener并仅实现以下内容:

ngAfterViewInit(): void {
    this.imageSrc = this.element.nativeElement.src
    this.element.nativeElement.src = "assets/loading-50px.svg";
    fetch(this.imageSrc).then(r => 
        this.element.nativeElement.src = this.imageSrc
    );
}

效果很棒!

1 个答案:

答案 0 :(得分:2)

您应该使用ngAfterViewInit(连同implements AfterViewInit)而不是ngOnInit

这将确保您的ElementRef已经存在。