You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

异步关联场景下,如何正确迁移@computed装饰器至@tracked结合getter的实现?

异步关联场景下,如何正确迁移@computed装饰器至@tracked结合getter的实现?

嗨,我明白你现在遇到的问题了——异步的hasMany关系确实给@computed转@tracked+getter带来了小麻烦,你之前的写法问题在于没有利用好Ember对异步关系的自动追踪机制,反而引入了额外的@tracked变量绕了弯路。

原来的@computed('comments.@each.authorName')会自动监听两个关键变化:一是异步comments加载完成的状态变化,二是每个comment的authorName属性更新。而你之前手动维护@tracked names的方式,并没有让getter真正依赖comments的状态,所以当comments从pending变为fulfilled时,getter不会自动重新计算,自然得不到正确的结果。

其实不需要额外的@tracked变量,直接在getter里处理异步状态就好,Ember的自动追踪会帮你搞定后续的更新:

@hasMany('comment', { async: true }) comments;

get authorNames() {
  // 处理加载中的状态
  if (this.comments.isPending) {
    return 'loading';
  }

  // 可选:处理加载失败的情况
  if (this.comments.isRejected) {
    return '加载评论失败';
  }

  // 加载完成后,mapBy会自动追踪每个comment的authorName变化
  return this.comments.mapBy('authorName').join(', ');
}

这个写法能生效的原因是:

  • 当异步comments处于pending状态时,getter返回"loading";一旦comments加载完成(isPending变为false),Ember的追踪系统会检测到这个状态变化,自动重新运行getter,返回拼接好的作者名。
  • 对于每个comment的authorName变化,mapBy('authorName')会自动依赖每个comment的该属性,只要有任何一个comment的authorName更新,getter就会重新计算并返回最新的结果,和原来的@computed('comments.@each.authorName')效果完全一致。

如果需要更精细的控制(比如缓存计算结果),也可以结合@cached装饰器,但在这个场景下其实没必要,因为getter的依赖已经被Ember正确追踪了。

备注:内容来源于stack exchange,提问作者mate89

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 12:57:58