如何为数组内属性创建别名?Ember.computed.alias使用问题
解决Ember中数组元素属性的别名问题
看起来你在尝试给数组内的对象属性创建计算别名时遇到了麻烦——直接用Ember.computed.alias('auth[0].username')确实可能不生效,因为Ember的计算属性别名在处理数组索引路径时,不会自动追踪数组本身的变化(比如数组元素被替换、重新排序时),而且语法上也不是这么用的。下面给你两种可行的解决方案:
方案一:使用带数组依赖的计算属性
如果你需要兼容旧版Ember,可以手动创建计算属性,明确依赖数组的变动:
// 示例组件/控制器代码 import Component from '@ember/component'; import { computed } from '@ember/object'; export default Component.extend({ auth: [{ username: "", password: "", }, { username: "", password: "", } ], defaultUsername: computed('auth.[]', function() { // 先判断auth数组是否存在且有第一个元素,避免报错 const firstAuth = this.get('auth')[0]; return firstAuth ? firstAuth.get('username') : ''; }), username: computed('auth.[]', function() { const secondAuth = this.get('auth')[1]; return secondAuth ? secondAuth.get('username') : ''; }) });
这里auth.[]是Ember中监听数组内容变动的依赖键,当数组里的元素被添加、移除或替换时,计算属性会重新计算。如果还需要追踪单个元素的username属性变化,可以把依赖键改成auth.@each.username:
defaultUsername: computed('auth.@each.username', function() { const firstAuth = this.get('auth')[0]; return firstAuth ? firstAuth.get('username') : ''; })
方案二:Ember Octane及以上版本使用Tracked属性
如果你用的是Ember 3.16+的Octane版本,推荐使用原生类和@tracked装饰器,写法更简洁直观:
import Component from '@glimmer/component'; import { tracked } from '@glimmer/tracking'; export default class MyComponent extends Component { @tracked auth = [{ username: "", password: "", }, { username: "", password: "", } ]; get defaultUsername() { return this.auth[0]?.username ?? ''; } get username() { return this.auth[1]?.username ?? ''; } }
这里的getter会自动追踪auth数组的变化,当数组元素或元素的username属性更新时,对应的getter会重新计算值,完全不需要手动声明依赖。
为什么直接用alias不行?
Ember.computed.alias适合绑定到固定的属性路径(比如model.username),但数组索引的路径(auth[0].username)不属于Ember能自动追踪的合法依赖键格式。Ember无法识别[0]这种索引语法作为依赖的一部分,所以别名不会随着数组元素的变化而更新,自然就无法生效啦。
内容的提问来源于stack exchange,提问作者randomgood
相关产品推荐
相关产品推荐

