如何使用Ember.computed.sort对belongsTo关联属性排序?
解决Ember中按异步belongsTo关联属性排序的问题
这个问题我之前也碰到过!原因在于你的rack是异步关联(async: true),Ember默认的sort计算属性没法直接解析嵌套的异步属性路径——当排序逻辑执行时,rack的数据可能还没从后端加载完成,自然拿不到rack.name的值。下面给你几种可行的解决方案:
方案1:自定义排序函数(最灵活)
放弃字符串形式的sortDefinition,直接写自定义排序逻辑,同时处理异步关联可能未加载的情况:
export default Ember.Controller.extend({ sortedTargets: Ember.computed('model.@each.rack.name', function() { const targets = this.get('model'); return targets.sort((targetA, targetB) => { // 先判断rack是否已加载,避免报错 const rackNameA = targetA.get('rack') ? targetA.get('rack.name') : ''; const rackNameB = targetB.get('rack') ? targetB.get('rack.name') : ''; // 用localeCompare做字符串自然排序 return rackNameA.localeCompare(rackNameB); }); }) });
这里的依赖键model.@each.rack.name会监听所有target的rack.name变化,确保数据更新时排序自动重新计算。
方案2:预加载关联数据(最简洁)
如果你的业务场景允许,可以在路由中预加载rack关联数据,让它变成同步属性,这样原来的写法就能生效:
// 对应的路由文件 export default Ember.Route.extend({ model() { // 使用include预加载rack关联,这样controller中拿到的rack是已加载的 return this.store.findAll('target', { include: 'rack' }); } });
预加载完成后,你原来的代码就可以正常工作了:
export default Ember.Controller.extend({ sortedTargets: Ember.computed.sort('model', 'sortDefinition'), sortDefinition: ['rack.name'] });
方案3:转换数组后排序
先把模型数组转换成包含同步rackName属性的对象数组,再用默认的sort逻辑:
export default Ember.Controller.extend({ // 先处理异步属性,生成带同步rackName的数组 targetsWithRackName: Ember.computed('model.@each.rack.name', function() { return this.get('model').map(target => ({ target, rackName: target.get('rack') ? target.get('rack.name') : '' })); }), // 基于转换后的数组排序 sortedTargets: Ember.computed.sort('targetsWithRackName', 'sortDefinition'), sortDefinition: ['rackName'] });
内容的提问来源于stack exchange,提问作者Rick
相关产品推荐
相关产品推荐

