2017-02-18 77 views
0

这里是我的情况,简化为:Ember用hasMany关系检索一条记录的计算属性?

// model/price-source.js 

export default DS.Model.extend({ 
    price: DS.attr('number'), 
    product: DS.belongsTo('product') 
)}; 

// model/product.js 

export default DS.Model.extend({ 
    priceSources: DS.hasMany('price-source') 
)}; 

在我的产品模板,我希望能够简单地引用源用最低的价格,就像这样:

// templates/products.hbs 

{{#each model as |product|}} 
<span>{{product.cheapestSource.price}} €</span> 
{{/each}} 

我怎么会去关于设置cheapestSource计算属性?我想我不得不做这样的事情:

// model/product.js 

    cheapestSource: Ember.computed('priceSources', function() { 
    let sources = this.get('priceSources'); 
    let cheapest = sources.get('firstObject'); 

    // iterate over sources and set cheapest to whichever has the lowest price 

    return cheapest; 
    }) 

的问题是,我根本不知道如何通过的hasMany关系循环(除了使用把手{{#each}}帮手),和计算出的属性是否可以包含来自另一个模型的单个Ember Data记录。是否有消息来源,如果有的话,怎么玩?

任何帮助和想法表示赞赏,谢谢。

回答

0

我通过将priceSources整理到计算属性sortedPrices中,然后调用模板中sortedPrices的firstObject来实现它。将立即用实际的解决方案编辑这篇文章。

它花了很长时间来测试,因为我没有意识到注释句柄块会破坏html内部的渲染。注意自我...


编辑:这做到了:

export default DS.Model.extend({ 
    priceSources: DS.hasMany('price-source'), 
    sortProperties: ['price:asc'], 
    sortedSources: Ember.computed.sort('priceSources', 'sortProperties') 
}); 

然后在模板:

<span>{{product.sortedSources.firstObject.price}} €</span> 

工程确定,没有一吨的代码。

0

这可以在需要使用cheapestSource的控制器上执行。

cheapestSource: Ember.computed('priceSources', function() { 
     let sources = this.get('priceSources'); 
     let cheapest = sources.get('firstObject'); 
     let array = sources.mapBy("price"); 
     let min = array.reduce(function(a, b, i, array) {return Math.min(a,b)}); 
     sources.forEach(function(source){ 
      if (source.get("price") == min){ 
      cheapest = source; 
      } 
     }); 
    return cheapest; 
    }) 

模型是有点难以实现你想要的这是为什么使用一个计算和模板后渲染计算成为你需要的对象。

cheapestSource: Ember.computed('priceSources', function() { 
     let product = this; 
     this.get('priceSources').then((sources)=>{ 
     let array = sources.mapBy("price"); 
     if(array.length>0){ 
     let min = array.reduce(function(a, b, i, array) {return Math.min(a,b)}); 
     sources.forEach(function(source){ 
      if (source.get("price") == min){ 
      product.set("cheapestSource", source); 
      } 
     }); 
     } 
    }); 
    }) 

当我有这样我使用主动型适配器on Rails和作为产品的一部分,在我的自定义序列返回例如cheapestSourcePrice然后在灰烬产品型号只需添加问题cheapestSourcePrice和模板{{} product.cheapestSourcePrice }你不要t want ember to do heavy lifting like this but if you don t控制服务器然后这样做。在将源设置为cheapesetSource之后,还有一件事情就是在刷新之前不再进行计算。如果你需要它留计算,您必须对模型增加一个属性然后设置他insted的例子

cheapestSource2:DS.attr()

这将允许它是一个对象

产品。设置(“cheapestSource2”,来源);

,然后在模板 {{product.cheapestSource}} {{product.cheapestSource2.price}}

您拨打第一个属性是有这么计算被调用。

+0

我正在阅读[作为承诺的关系](https://guides.emberjs.com/v2.11.0/models/relationships/#toc_relationsships-as-promises)指南。我们可以像你一样直接访问它吗?如果可能的话,在你的答案中解释..只是为了我的学习。谢谢。还有依赖键'priceSources。@ each.price'可能会有用。一旦你阅读,我将删除我的评论 – kumkanillam

+0

我在控制器上做了这个,现在我明白你为什么要问这个问题,他在模型thx中做了检查。 –

+0

@ Sedad.Kosovac不幸的是没有priceSource对象显示出来(在Ember Inspector中)。我没有得到错误。我尝试了'return this.get('priceSources')。get('firstObject')',也试过'返回this.get('priceSources.firstObject')',但没有。 因为我将需要排序来源,更好的方法来获得最便宜的可能是首先排序,然后检索sortedSources计算属性中的firstObject。 –

0

如果你有时间也试试这个解决方案。 this.get('priceSources')它返回Promise,所以你需要访问方法中的结果并将其包装在DS.PromiseObject中,以便可以像访问模板中的普通对象那样访问它。

cheapestSource: Ember.computed('[email protected]', function() { 
     return DS.PromiseObject.create({ 
      promise: this.get('priceSources').then(sources => { 
       let resultObj = {} 
        //sources is normal array you can apply your logic and set resultObj 
       return resultObj; 
      }) 
     }); 
    }) 
+0

这是应该进入组件(或控制器)或模型?尝试它在模型中,得到这个: 'Uncaught TypeError:this.get(...)。然后不是一个函数',我认为这将是一个很好的解决方案,因为我希望在排序源文件后将其作为计算属性最便宜,例如在' source =>'函数,我可以只返回sources.firstObject,sources.get('firstObject'),sources [0]或其他任何正确的语法 –

+0

您可以在模型中定义它,默认为'priceSources:DS。 hasMany('price-source',{async:true})'。如果async属性为true,那么它返回Promise,所以'then'是一件事,如果它的false返回DS.ManyArray,那么'then'不是你的事情,所以你会出现这个错误,我没有找到任何例子,我只是希望这个[用于加载的烬点火器文章](ht tps://emberigniter.com/guide-promises-computed-properties/)@VilleLehtinen – kumkanillam

相关问题