首页 > 解决方案 > Angular 组件在 NgbModal 中显示并在 html 模板中使用(加载)事件处理程序时不断重新渲染

问题描述

当引导程序的模态对话框中的组件时,它会每秒重新渲染几次。(我在浏览器开发人员工具中看到它)。

该组件如下所示:

@Component({
  selector: 'app-takeover',
  encapsulation: ViewEncapsulation.None,
  changeDetection: ChangeDetectionStrategy.OnPush,
  template: `

<iframe #iframe 
        [src]="sanitizer.bypassSecurityTrustResourceUrl(takeover.IframeUrl)"
        sandbox="allow-same-origin" 
        (load)="iframe_load($event)">
</iframe>

   `,
})
export class TakeoverComponent {

  constructor(
     public sanitizer: DomSanitizer
  ) { }

  takeover: Takeover;

  @ViewChild('iframe') iframeRef: ElementRef<HTMLIFrameElement>;

  iframe_load(event) { }
}

我这样展示它:

let modalRef = this.modalService.open(TakeoverComponent);
let component = modalRef.componentInstance as TakeoverComponent;
component.takeover = takeover;

当我从模板中删除 (load)="iframe_load($event)" 时,它只按预期呈现一次。

为什么它不断重新渲染 DOM,我如何防止它这样做?

“@angular/core”:“~7.2.0”、“@ng-bootstrap/ng-bootstrap”:“^4.2.1”、“zone.js”:“~0.8.26”

标签: javascriptangularangular7ng-bootstrapangular-lifecycle-hooks

解决方案


这可能是因为:

<iframe 
  #iframe 
  [src]="sanitizer.bypassSecurityTrustResourceUrl(takeover.IframeUrl)" 
  sandbox="allow-same-origin" 
  (load)="iframe_load($event)">
</iframe>

您已将src上的属性绑定iframe到方法。正在发生的事情是在每次更改检测时都会调用该方法。因此重新渲染。

考虑使用 apipe来防止重新渲染:

<iframe 
  #iframe 
  [src]="takeover.IframeUrl | safe: 'url'" 
  sandbox="allow-same-origin" 
  (load)="iframe_load($event)">
</iframe>

从我的回答here中获取safe管道实现。

PS:我没有对此进行测试,但应该可以正常工作。

将方法调用分配给属性绑定、属性绑定和字符串插值可能会导致不必要的重新渲染/性能损失。我在一篇Medium 文章中很快谈到了这方面。您可能也想阅读它。

还有一个StackOverflow Answer讨论了这个问题。


推荐阅读