【问题标题】:ngStyle VS Renderer2 ? What should I use?ngStyle VS Renderer2 ?我应该使用什么?
【发布时间】:2018-10-16 00:24:12
【问题描述】:

我正在使用 Angular 5.2.9。

我想知道什么时候应该使用 Renderer2 而不是 ngStyle ?哪个是最好的解决方案?

1:<div #div>FOO BAR</div>

  @ViewChild('div') div: ElementRef;

  constructor(private renderer: Renderer2) {}

  ngAfterViewInit() {
      this.renderer.setStyle(this.div.nativeElement, 'background', 'blue');
  }

2:<div [ngStyle]="styleValue">FOO BAR</div>

  styleValue: any = {};

  ngAfterViewInit() {
      this.styleValue = {background: 'blue'};
  }

我知道在 ngFor 中使用“ngStyle”更容易,例如:

<div ngFor="let elem of array" [ngStyle]="styleValue">

否则你应该为这种情况做:&lt;div ngFor="let elem of array" #div&gt;FOO BAR&lt;/div&gt;

  @ViewChildren('div') divs: QueryList<ElementRef>;

  constructor(private renderer: Renderer2) {}

  ngAfterViewInit() {
     this.divs.change.subscribe(() => {
        this.toFlipArray.forEach((div) => {
            this.renderer.setStyle(this.div.nativeElement, 'background', 'blue');
        })
     }
  }

在 ngFor 中使用 Renderer2 的时间似乎更长,而且我什至没有终止订阅。

性能有区别吗?也许在别的地方?

【问题讨论】:

    标签: angular ngfor ng-style angular-renderer2


    【解决方案1】:

    ngStylerenderer.setStyle 都用于动态设置组件样式

    renderer.setStyle 看起来优先于[ngStyle],即使ngStyle 看起来是一种嵌入样式。

    演示示例:

    https://stackblitz.com/edit/angular-jtdk4z?file=src%2Fapp%2Fapp.component.html

    查看ngStyle的内部实现时:

    https://github.com/angular/angular/blob/master/packages/common/src/directives/ng_style.ts

    看起来它本身是使用renderer.setStyle实现的

    @Directive({selector: '[ngStyle]'})
    export class NgStyle implements DoCheck {
      private _ngStyle: {[key: string]: string};
      private _differ: KeyValueDiffer<string, string|number>;
    
      constructor(
          private _differs: KeyValueDiffers, private _ngEl: ElementRef, private _renderer: Renderer2) {}
    
      @Input()
      set ngStyle(v: {[key: string]: string}) {
        this._ngStyle = v;
        if (!this._differ && v) {
          this._differ = this._differs.find(v).create();
        }
      }
    
      ngDoCheck() {
        if (this._differ) {
          const changes = this._differ.diff(this._ngStyle);
          if (changes) {
            this._applyChanges(changes);
          }
        }
      }
    
      private _applyChanges(changes: KeyValueChanges<string, string|number>): void {
        changes.forEachRemovedItem((record) => this._setStyle(record.key, null));
        changes.forEachAddedItem((record) => this._setStyle(record.key, record.currentValue));
        changes.forEachChangedItem((record) => this._setStyle(record.key, record.currentValue));
      }
    
      private _setStyle(nameAndUnit: string, value: string|number|null|undefined): void {
        const [name, unit] = nameAndUnit.split('.');
        value = value != null && unit ? `${value}${unit}` : value;
    
        if (value != null) {
          this._renderer.setStyle(this._ngEl.nativeElement, name, value as string);
        } else {
          this._renderer.removeStyle(this._ngEl.nativeElement, name);
        }
    }
    

    【讨论】:

    • 如果 ngStyle 正在使用 Renderer,那么我们可以假设它也在使用 Renderer2 吗?
    • 对,看代码中构造函数注入了什么:private _renderer: Renderer2。你看到 Renderer2 被注入了。
    • 太棒了,所以它们是一样的;并且不用担心 [ngStyle] 会暴露漏洞。
    • Renderer2, provides an API that can safely be used。通过快速搜索,我找到了该链接,但您可以搜索更多内容以找到 Angular App Security 的最佳实践。所以[ngStyle] 不应该暴露漏洞。
    猜你喜欢
    • 2021-12-19
    • 2019-11-04
    • 2015-03-09
    • 2019-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 2017-11-18
    相关资源
    最近更新 更多