【问题标题】:Angular *ngIf binding to functionAngular *ngIf 绑定到函数
【发布时间】:2018-08-03 13:50:28
【问题描述】:

我想问一下 *ngIf 绑定到函数返回值的问题。比较 *ngIf 绑定到属性时是否会产生性能开销。

这只是询问概念的示例代码,数据结构比DataService中的复杂。启用标志将保存在地图对象中。这只是一个简单的表达方式:

在打字稿服务中

export class DataService() {
   private enable: boolean;

   isEnable() {
      return enable;
   }

   getEnableValue() {
      return enable;
   }

   update(flag: boolean) {
      enable = flag;
   }
}

在html中,

<div *ngIf="isEnable()">
    <p> {{ testObject.value }}</p>
</div>

在打字稿中,

isEnable() {
   return this.dataService.isEnable();
}

对比

在html中,

<div *ngIf="isEnable">
    <p> {{ testObject.value }}</p>
</div>

在打字稿中,

isEnable: boolean;
ngOnInit() {
    isEnable = this.dataService.getEnableValue()
}

对于*ngIf="isEnable",我可以理解。但是对于函数绑定,是角度检查函数中的属性并监控它的变化吗?有什么性能差异吗?

非常感谢。

【问题讨论】:

  • console.log("hello") 添加到您的函数中,您就会知道。它在每次更改检测时调用,以了解是否应该从 DOM 中添加或删除元素。
  • 它会根据您的功能的复杂性而产生性能差异。如果您只有一个属性绑定,那么它只是检查该属性。如果您有一个循环遍历数组中的 3,000 个项目的函数,那么该循环将在每次触发更改检测时运行。所以是的,在性能方面,属性变量更好。
  • 我知道 *ngIf 是在 DOM 中添加或删除。可能是我的问题不清楚。我想问的是,分配给*ngIf的函数的值变化和属性的值变化,是否会影响2种不同风格写作的性能?
  • 这取决于this.dataService.isEnable()在返回值之前必须做什么。
  • Angular 将不得不重新评估函数以了解它是否已更改。我会使用 Subject 或 BehaviourSubject 来避免这种情况。

标签: angular


【解决方案1】:

从技术上讲,性能没有明显差异。

当 Angular 编译 AOT 模板时,它们会被转换成 JavaScript 源代码,而所有这些单向绑定都会变成函数。

因此,在执行以下任何操作时,我不应该有任何明显的表现。

export class MyComponent {
     public title1: string;

     public get title2(): stirng {
          return this.title1;
     }

     public getTitle3(): string {
          return this.title1;
     }
}

使用上述所有 3 个将具有大致相同的性能。

缺点

使用函数有副作用。

  • 它打破了模板的干性原则
  • 您无法看到模板有多复杂
  • 性能隐藏在函数内部

我还发现您倾向于在模板中做更多的工作。当您调用函数时,可以更轻松地使用*ngIf*ngFor 和其他逻辑组件。

当您阅读组件的源代码时,您并没有获得完整的图片。很多业务逻辑都是在模板里面做的,看模板看不出来怎么看,因为模板里面有很多逻辑。

【讨论】:

  • 如果 DataService 中的 isEnable() 必须访问地图并检索其值: const object = map.get('type1');返回对象。启用。每次地图内容变化都会触发评估功能吗?
  • @rodent_la 你混淆了性能和变化检测。两者是不同的话题。如果您使用 OnPush(您应该使用),那么服务中的任何更改都不会触发模板渲染,因为您应该将数据推送到模板。
  • 非常感谢。
  • 确实会影响性能!当您使用函数而不是不可变或原始数据类型(布尔、字符串、数字)时,角度必须评估每个应用程序滴答/更改跟踪滴答的函数!这是你能做的最糟糕的事情!使用 observables (rxjs) 或预先评估状态并将其保存在公共可访问属性中以绑定到模板上!参考:stackoverflow.com/questions/49320756/…
猜你喜欢
  • 2017-06-03
  • 2020-06-21
  • 2018-04-18
  • 2020-09-28
  • 1970-01-01
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 2020-11-30
相关资源
最近更新 更多