当前位置: 首页 > 知识库问答 >
问题:

对于角度属性,它们不应该是私有的并通过方法访问吗?

葛念
2023-03-14

我对Angular/Typescripting有点困惑。我认为应该隐藏属性,以防止对属性值进行任何可能的外部更改。

例如:

export class Foo{
  private _bar: string;

  constructor(private bar: string){
    this._bar = bar;
  }

  public get bindBar(): string {
      return this._bar;
  }
}

还有一些模板

<span>{{ bindBar }}</span>

但是在阅读中,由于在页面上发生的每次更改检测下都会调用方法,因此绑定到html模板中的方法存在性能问题。

我看到的选择是要么将其作为公共财产,要么使用管道。

管道似乎有点矫枉过正,必须为需要绑定的页面中的每个属性实现,并且公共变量几乎总是不行的。

我在Angular网站上找不到任何关于如何实现绑定而不会对性能产生负面影响的明确方向,但这种管道式的做法似乎并不正确。

有人可以解释一下吗?

正如您在示例中所看到的,它没有绑定到组件,因为触发的事件会影响其他组件。我的堆栈闪电战 2 组件测试

共有2个答案

池麒
2023-03-14

在打字稿中,使用公共变量并直接访问它们大多是安全的。绑定时,使用方法时事情往往会发生偏差,因此建议在绑定中使用变量。

司徒翼
2023-03-14

这个吸气剂

  public get bindBar(): string {
      return this._bar;
  }

不会降低应用程序的性能。调用它所需的时间与直接引用变量所需的时间大致相同。模板中的所有变量也会在每次检测到更改时被引用,以检查它们是否已更改。因此,在模板中调用它与引用公共变量没有什么不同。

也就是说,如果您想使变量为只读,您可以只使用<code>readonly</code>关键字。

readonly bar: string;

不相信我?这里有一个测试:

https://stackblitz.com/edit/angular-ivy-zgjwnw?file=src/app/app.component.ts

超过一百万个变化检测周期,这两种策略用我的硬件大约需要650毫秒。

在更改检测期间调用方法的唯一时间是这些方法是否花费大量时间,或者您正在向 API 发出请求。切勿将这些类型的方法调用放在模板中,除非将它们绑定到事件。

如果您担心性能,您应该更关心实际触发更改检测的次数,以及每次检查多少组件。默认的更改检测策略是检查所有当前组件模板中可能更改某些内容的每个操作的每个变量和方法调用。

OnPush 更改检测策略允许您在检查组件模板时进行更改,而 ChangeDetectorRef.detach() 服务方法允许您完全分离组件,使其不自动检查。

这是一篇很棒的文章,可以了解更多信息:

https://blog.angular-university.io/how-does-angular-2-change-detection-really-work/

我强烈建议在调用ChangeDetectorRef.detect()并在调试器中遍历更改检测周期之前放置一个断点。您会看到更改检测器将模板中任何插值值的最后一个值(无论它们是属性还是方法调用的结果)保存在一个名为lView(最后一个视图)的对象中。然后在更改检测周期中,它再次重新计算这些插值值——无论这意味着引用变量还是调用方法。如果任何值不同,那么更改检测器将引用相关的html节点并更改它的值。

在管道的上下文中,变化检测器将检查输入值,并且仅在该值发生变化时调用管道。那是因为管道被假定为纯函数(输出只依赖于输入)。所以如果你在调用一个耗时的纯方法,让它成为管道会更有效率。示例:格式化字符串、执行验证、数学等式、深度比较等。

 类似资料:
  • 这是我的班级。我想将该属性保持为私有,并且必须通过getter和setter来访问该属性。 我试图创建一个对象并访问该属性,但失败了。当我浏览文档时,我发现了一件有趣的事情,“getter总是具有与属性相同的可见性”。链接 科特林的正确方法是什么?

  • 问题内容: 我有一个带有一系列对象属性的对象,这些对象属性具有以下相似的结构(这是从服务返回数据的方式): 当我执行ng-repeat时,我可以遍历所有这5个对象,例如: 但是, 我真正想要做的是仅对那些不是“ foo”类型的项进行迭代 ,即3次迭代而不是5次。我知道可以以某种方式利用过滤器来执行此操作,但是我不确定如何执行。我尝试了以下方法: 但这不起作用。实际上,即使执行以下操作以将对象限制为

  • 我是Spring启动的新手。我尝试使用Spring Security和Hibernate实现登录和注册功能。 首先,我使用Hibernate从数据库生成持久性映射实体类。我需要在UserEntity类中实现UserDetails接口,但问题发生了。 我无法在UserDetails中实现这些方法。 尝试实现GetAuthories时出错。以下是错误信息。 “Basic”属性类型不应是容器。检查信息:

  • 声纳有一条规则: 不访问实例数据的方法应该是 不访问实例数据的私有方法可以是静态的,以防止对方法契约的任何误解。 我在一个从匿名内部类创建新对象的方法中有此警报。 How是一个非静态字段。我无法对非静态字段进行静态引用。正如sonar所说,我不能将此方法设置为静态,因为存在一个访问实例数据的方法。 我的问题是,Sonar没有在匿名内部类中看到的使用,因此Sonar向我显示了警告:不访问实例数据的私

  • 问题内容: 假设我有一个要实例化的类。我在类中有几个私有的“帮助器”方法,它们不需要访问任何类成员,而仅对它们的参数进行操作,并返回结果。 有没有指定任何特别的原因,并为静态方法-或任何特别的理由不? 将它们设置为非静态无疑是最容易的,即使它们可以肯定是静态的而不会引起任何问题。 问题答案: 我更喜欢这样的帮助方法; 这将使读者清楚地知道他们不会修改对象的状态。我的IDE还将以斜体显​​示对静态方

  • 问题内容: 假设我有一个带有某些属性的类。如何最好地(在Pythonic- OOP中)访问这些属性?就像吗?还是写get访问器?这些东西可接受的命名方式是什么? 编辑: 您能否详细说明使用单引号或双引号下划线命名属性的最佳做法?我在大多数模块中看到使用单个下划线。 如果已经问过这个问题(虽然搜索没有带来结果,但我有一个直觉,请指出)-我将结束这个问题。 问题答案: 通常公认的做事方式只是使用简单的