【问题标题】:Angular Image Sanitization Optimization角度图像清理优化
【发布时间】:2018-08-10 03:16:19
【问题描述】:

我有一个关于 Angular 5 中图像资源的 DomSanitizer 的问题。我主要在从 Firestore 获取集合并在 ngFor 中动态设置 [src][style.background-image] 时使用它。因此,最初当意识到需要对 DOM 上使用的资源进行清理时,我创建了一个 Image Sanitizer Service,其中包含用于不同类型清理的方法:

import { Injectable } from '@angular/core';
import { DomSanitizer, SafeResourceUrl, SafeUrl } from '@angular/platform-browser';

@Injectable()
export class UrlSanitizerService {

  constructor(
    private sani: DomSanitizer
  ) { }

  getSanitizedUrl(url) {
    return this.sani.bypassSecurityTrustResourceUrl(url);
  }

  getSanitizedStyle(url) {
    return this.sani.bypassSecurityTrustStyle(`url(${url})`);
  }

  getSanitizedHtml(html) {
    return this.sani.bypassSecurityTrustHtml(html);
  }

}

然后我将其提供给需要使用从可观察对象加载的动态数据的任何模块或组件。然后我意识到我需要使用这两种方法之一。 1) 在组件中订阅我的 Observable 数据并在我的标记中循环数据集之前清理 url:

  getLocationDetails() {
    this.businesses = this.ls.getLocations();
    this.businesses.subscribe((locations: any) => {
      locations.map((data) => {
       data.photoUrl ? data.photoUrl = this.urlS.getSanitizedStyle(data.photoUrl) : console.log('no-photo');
      });
    });
  }

在循环浏览几个文档时,这不是很耗费资源,但如果数据集有大量文档,那么这可能会很昂贵。 2)然后我也尝试在[src]标签的标记中使用此方法:

  sanitizeImageStyle(url) {
    return this.urlS.getSanitizedStyle(url);
  }

像这样:

<div [style.background-image]="sanitizeImageStyle(photoUrl)"></div>

但是在方法中记录了 url 之后,我意识到这是在 DOM 上不断运行的,而且成本也很高。所以我还有一个想法,那就是使用管道来清理 url,因为它在 [style.background-image] 输入中使用。像这样:

export class UrlSanitizerPipe implements PipeTransform {

  states: any[];

  constructor(
    private urlS: UrlSanitizerService
  ) {
    this.states = [
      'style',
      'resource'
    ];
  }

  transform(value: any, args?: any): any {
    if (value) {
      if (args) {
        switch (args) {
          case this.states[0]:
            return this.urlS.getSanitizedStyle(value);
          case this.states[1]:
            return this.urlS.getSanitizedUrl(value);
          default:
            return value;
        }
      }
    }
  }

}

然后像这样使用管道:

<div [style.background-image]="photoUrl | urlSanitizer: 'style'"></div>

所以我试图在浏览器上使其尽可能具有成本效益。我的问题是我应该像上面那样在管道中使用它,还是我应该使用 url 字符串的 Input() 创建到它自己的组件中,然后将其转换为经过清理的资源并设置样式或其模板的资源?我很欣赏所有的洞察力。提前致谢!

【问题讨论】:

    标签: angular sanitization angular-pipe


    【解决方案1】:

    当您从服务中的API接收数据时,您可以映射操作员。

    【讨论】: