ngDoCheck VS 使用函数作为属性值 - 性能差异
Posted
技术标签:
【中文标题】ngDoCheck VS 使用函数作为属性值 - 性能差异【英文标题】:ngDoCheck VS using function as attribute value - Performace difference 【发布时间】:2020-03-22 08:09:08 【问题描述】:我在网页中有一个锚标记,其 href 值取决于属性不受此组件控制的服务。服务详细信息是异步填充的。
为了获取服务详细信息并创建 href 值,我想到了两种方法。 我的问题是 - 在性能方面哪个更好?什么应该是更好的选择?
使用函数作为 href 属性
这会导致函数被连续调用。
// Inside component.html
<div>
<a [href]="getDetailsLink()"></a>
</div>
// Inside component.ts
@Component( selector: 'user', template: `...` )
class UserComponent implements DoCheck
public detailsLink: string;
constructor(
private userService: UserService
)
public getDetailsLink(): string
// Based on the below property
const checkSomeProperty = this.userService.checkSomeProperty;
// Construct details link
this.detailsLink = `https://www.something.com/users/$this.userService.checkSomeProperty.someValue`;
使用 ngDoCheck
// Inside component.html
<div>
<a [href]="detailsLink"></a>
</div>
// Inside component.ts
@Component( selector: 'user', template: `...` )
class UserComponent implements DoCheck
public detailsLink: string;
constructor(
private userService: UserService
)
ngDoCheck()
if (this.userService.checkSomeProperty)
// Check changes for the property
// Perform required action
// Construct details link
this.detailsLink = `https://www.something.com/users/$this.userService.checkSomeProperty.someValue`;
感谢您阅读到这里。任何指导表示赞赏
【问题讨论】:
两者都不是。使用可观察的。这就是他们的目的。 【参考方案1】:您有一些业务逻辑来生成该 url,而服务是业务逻辑的地方。解决方案一是这里的方法。
话虽如此,基于链接的https://www.something.com/users/
部分是否为静态的事实,我也会考虑使用管道来构建这样的网址,以利用记忆。
你最终会得到类似的东西:
<a [href]="someUser | buildLink"></a>
【讨论】:
如果我使用管道,我想我仍然会遇到 this.userService.checkSomeProperty 中数据不可用的问题? 此外,对于简单的手动检查,管道看起来可能比 ngDoCheck 具有额外的性能开销indepth.dev/…【参考方案2】:我认为第一种方法应该绝对避免。
如果以这种方式使用函数,它将在每个可能影响性能的更改检测周期中被调用(有时,以可见的方式)。
ngDoCheck 还将在每个更改检测周期中调用,因此我会避免在此处添加任何严肃的工作。
Massimiliano 提出了一种方法:使用管道,这样您就可以利用记忆的力量。 Here is a great talk 增强了使用管道的好处。
然而,我认为对于这种情况,管道是不需要的。
如果你说这个值依赖于一个服务异步提供的值,你可以把这个逻辑包装成Subjects和Observers。
user.service.ts
export class UserService
private linkChangedSubj = new Subject();
get linkChanged$ ()
return this.linkChangedSubj.asObservable();
changeLink (newLink)
/* ... */
this.linkChangedSubj.next(newLink);
user.component.ts
export class UserComponent
constructor (private userService: UserService)
ngOnInit ()
this.userService.linkChanged$
.pipe(takeUntil(this.unsubscribe$))
.subscribe(newLink => this.detailsLink = newLink)
【讨论】:
这是解决这个问题的方法,甚至可以通过使用异步管道而不是使用unsubscribe
信号方法来改进。在每个更改检测周期检查某些服务属性将永远不会执行良好。这就是主题的用途。以上是关于ngDoCheck VS 使用函数作为属性值 - 性能差异的主要内容,如果未能解决你的问题,请参考以下文章
无法从 VS2019 中的 Boost 属性树映射值中获取值()