如何在 Angular 中缓存组件并基于自定义指令重用?

How to cache component and reuse based on custom directive in Angular?

提问人:Margaret Nguyen 提问时间:10/26/2023 更新时间:10/26/2023 访问量:34

问:

我有一个自定义指令,用于评估用户访问组件的权限,比如说 .ngIfPerm

set ngIfPerm(val) {
  // set val
  if (/*true condition*/) {
    this.viewContainer.createEmbbededView(this.templateRef)
  } else {
    this.viewContainer.clear()
  }
}

此指令放在一些在表的行上重复的按钮中,以决定是否应呈现和显示该按钮。例如,如果用户具有权限,则此按钮将显示在表的每一行上:EDIT

<button *ngIfPerm="EDIT" (click)="edit(rowData)>Edit</button>

问题是,Angular 重新渲染了这个按钮,而不是在表格的第二行重用它。如果将按钮放置在多个位置,这会导致应用程序的性能急剧下降。

我的问题是,有没有一种机制可以帮助在首次成功渲染后缓存此按钮,并在再次调用时重用它?(如缓存模板)

我已经读过,但它是针对 AngularJS 的,并且我正在将 Angular9 与 TypeScript 一起使用。templateCache

提前致谢。

Angular 模板 缓存 指令

评论


答:

0赞 Chintan Dhokai 10/26/2023 #1

这应该会提高应用程序的性能,因为 Angular 将不再需要在表格的每一行上重新渲染按钮。

import { Directive, Input, ViewContainerRef, TemplateRef } from '@angular/core';

@Directive({
  selector: '[cacheComponent]'
})
export class CacheComponentDirective {
  private hasView = false;

  constructor(
    private viewContainer: ViewContainerRef,
    private templateRef: TemplateRef<any>
  ) {}

  @Input() set cacheComponent(condition: boolean) {
    if (condition && !this.hasView) {
      this.viewContainer.createEmbeddedView(this.templateRef);
      this.hasView = true;
    } else if (!condition && this.hasView) {
      this.viewContainer.clear();
      this.hasView = false;
    }
  }
}
<table>
  <tr *ngFor="let rowData of data">
    <td>
      <button *cacheComponent="hasEditPermission(rowData)" (click)="edit(rowData)">Edit</button>
    </td>
  </tr>
</table>

评论

0赞 Margaret Nguyen 10/26/2023
谢谢你的建议。请问如何导入,因为IDE抛出错误TemplateCacheService"@angular/compiler/compiler" has no exported member 'TemplateCacheService'
0赞 Chintan Dhokai 10/26/2023
import { TemplateCacheService } from '@angular/compiler';tsconfig.json文件:“allowSyntheticDefaultImports”: true,
0赞 Margaret Nguyen 10/26/2023
我仍然无法导入它。也许是元素不存在的问题。你能把文件递给我吗?非常感谢TemplateCacheService
0赞 Chintan Dhokai 10/26/2023
但是,如果您使用的是旧版本的 Angular,您将无法导入 TemplateCacheService,因为它直到 Angular 9 才引入。
0赞 Chintan Dhokai 10/26/2023
检查更新的解决方案是否适合您?