如何在Angular2 +中轻轻更改img src

时间:2019-01-22 10:11:02

标签: html angular

当我动态更改img的{​​{1}}属性时,在加载新图像时会显示旧图像。

我有一个显示一些数据的组件:文本和图像。点击后,基础数据就会更改(即来自服务器的新数据)。单击后,文本会立即更改,但是在加载新图像时组件会显示旧图像。加载新图像后,将在视觉上显示该图像,这可能会花费大量时间。

在实际应用中,可以单击按钮获得产品详细信息和更改产品。立即替换所有数据,但不替换图像。

不破坏(重用)组件时存在问题。

点击后,我已经尝试了清除图像src,但是没有用。

我在模板中具有简单的绑定

src

点击时图像发生变化

img [src]="img.url" style="width: 300px; height: 300px">
<p>{{ img.text }}</p>

您可以在https://stackblitz.com/edit/angular-cojqnf此处查看示例应用

是否可以更好地控制此图像更改过程?最好在单击时清除图像,然后等待背景为空的新图像。

2 个答案:

答案 0 :(得分:1)

最后,我通过利用(load)img上的[ngStyle]事件来实现了自己想要的目标。

在模板中,我添加了加载处理程序和样式:

<img [src]="img.url" style="width: 300px; height: 300px" (load)="loaded()"
 [ngStyle]="{'display': imgVisible ? 'block' : 'none'}">

在后端:

imgVisible = true;

并且在更改数据时,还隐藏图像:

this.imgVisible = false;

接下来,在加载图像时,显示图像(请注意!当新旧图像具有相同的URL时,不会引发此事件;如果是这种情况,则需要有条件地隐藏图像)

loaded(): void {
  this.imgVisible = true;
}

完整的解决方案代码:https://stackblitz.com/edit/angular-ewptj7

我不是这种解决方案的忠实拥护者。当您有更多图像时,可能很难应用。

欢迎所有更好的解决方案。

答案 1 :(得分:1)

我通过您的stackblitz演示进行了一些改动,基本上将您的代码包装在ImageGhostDirective中以使其可重用。该指令使用src来监听MutationObserver属性上的所有更改,以更改样式。在'load'事件上使用HostListener,它将样式恢复为普通样式。我从第一次加载的不透明度为0开始,然后是连续图像更改之间的不透明度为0.2,但这是完全任意的,可以用微调器或任何类型的占位符代替...

以下是堆叠闪电战的链接:https://stackblitz.com/edit/angular-image-ghost-directive

<img [src]="'https://loremflickr.com/300/300?random=' + index"
     style="width: 300px; height: 300px" imgGhost>
@Directive({
  selector: 'img[imgGhost]'
})
export class ImageGhostDirective implements OnDestroy {
  private changes: MutationObserver;

  constructor(private elementRef: ElementRef) {
    this.changes = new MutationObserver((mutations: MutationRecord[]) =>
      mutations.filter(m => m.attributeName === 'src').forEach(() => this.opacity = 0.2)
    );

    this.changes.observe(this.elementRef.nativeElement, {
      attributes: true,
      childList: false,
      characterData: false
    });
  }

  ngOnDestroy(): void {
    this.changes.disconnect();
  }

  @HostBinding('style.display') display = 'block';
  @HostBinding('style.opacity') opacity = 0;

  @HostListener('load')
  onLoad(): void {
    this.opacity = 1;
  }
}

通过使用指令装饰器中的img选择器,也可以告诉Angular自动将此指令附加到每个img:not([imgGhost])元素。这样,您无需在应用程序中的每个图像上手动放置指令。

希望这很有用。