【问题标题】:Valid way to access a private property in angular2 template?在 angular2 模板中访问私有属性的有效方法?
【发布时间】:2018-06-17 07:41:54
【问题描述】:

我有一个类UserList 有一个私有内部变量,该变量设计为仅对访问函数可用。如何在 ngFor 绑定中以高效的方式访问该内部列表?

class UserList {
  private users:user[] = []
  public addUser():void{..} 
  public removeUser():void{..}
  public listUsers():user[]{
    return this.users; //this is the only way to access the private users list
  } 
}

然后在某个组件中..

@component ({...})
class AppComponent {
  users:UserList = new UserList();
}

在该组件的模板中,getter 函数被调用..

<span *ngFor="let user in users.listUsers()">
  {{ user.username }}
</span>

很明显,这并不能很好地执行,因为 Angular 不可能知道此列表何时更改,并且必须不断调用 users.listUsers() 以保持视图更新。我可以以某种方式限制这种行为并通知 Angular 该列表已随某些事件发生更改吗?我不想公开列表,也不想直接在模板中访问私有属性。

参考资料: Angular2 - should private variables be accessible in the template?

更新解决方案:

Amit 关于使用 OnPush 更改检测的建议得到了解决。我在用户服务中构建了一个回调,以通知任何使用它的组件私有用户列表的更改。然后应用程序组件可以调用 markForChange() 来更新视图。这让我可以在不破坏依赖注入模式或我试图强制执行的封装的情况下刷新视图。

我仍然对这种方法感到不满意,因为更改检测方案会影响整个组件而不是元素。对我来说,Angular 无法有效地将函数的结果绑定到元素上似乎很奇怪,而不会造成性能漏洞或破坏设计模式,或者重新配置整个组件以观察该行为。

【问题讨论】:

  • 也许为相关变量创建getter/setter?
  • 这就是我所做的。我希望私人列表中只有吸气剂可以访问。但这限制了我可以在模板中绑定的内容。我必须绑定 getter 函数,这意味着 angular 必须不断调用该函数以查看数据是否已更改。我现在正在研究 OnPush 更改检测

标签: angular typescript


【解决方案1】:

您可以使用 OnPush 更改检测策略,并在您知道列表发生更改时标记组件以检测更改。

【讨论】:

  • 我需要对如何使用 OnPush 更改检测做一些研究,然后我再评论...
  • 您基本上将您的组件设置为该更改策略,注入ChanageDetectorRef,并在您认为需要重新评估视图时调用markForCheck()
  • 这很好用。我在 usersService 中构建了一个回调,它将通知应用程序组件的更改。然后,应用程序组件将调用 markForCheck(),它大大降低了对 getter 函数进行不必要轮询的频率。我仍然不相信没有更好的方法将函数的返回值绑定到模板 - 请参阅我的问题更新。
  • 我感觉到你了。我猜如果某些函数可以标记为纯函数,它们只能在输入更改后调用它们(它们已经知道如何正确检测)
【解决方案2】:

这不应该。我要求你不要这样做。它将破坏DI
请从您的服务中调用您的私有数据并为模板创建一个公共变量

【讨论】:

  • 我可以将 userList 视为一项服务(并称之为 usersService)并在应用程序组件中保留 usersService.listUsers() 的最新输出?这样,模板就可以绑定到最近的数据副本。这就是我几乎要使用的,但我需要某种 onChange 事件,应用程序组件控制器可以订阅该事件,以防止数据过时。我不确定这是否是标准方法,或者大多数人是否会以某种方式在模板中绑定访问器 getList()。
  • @AustinMcCool 订阅后可以更改您的数据。您可以编辑您的问题并显示您之前尝试过的内容吗
猜你喜欢
  • 2016-04-07
  • 1970-01-01
  • 2017-03-30
  • 2020-03-04
  • 2014-11-21
  • 2012-02-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多