Ember计算属性,用于从hasMany关系中检索一条记录?

时间:2017-02-18 14:35:27

标签: ember.js ember-data has-many computed-properties

这是我的情况,简化:

// 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数据记录。来源。@每个人都会以某种方式发挥作用,如果是这样,怎么样?

感谢任何帮助和想法,谢谢。

3 个答案:

答案 0 :(得分:1)

我通过将priceSources排序为计算属性sortedPrices,然后在模板中调用sortedPrices的firstObject来实现它。将很快用实际解决方案编辑这篇文章。

我需要花费很长时间才能测试,因为我没有意识到注释掉手柄块会破坏它们内部的html渲染。注意自己......

编辑:这样做了:

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

然后在模板中:

x

工作正常,没有大量代码。

答案 1 :(得分: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);
          } 
       });
      }
    });
  })

当我遇到这样的问题时,我在Rails上使用活动模型适配器,并在我的自定义序列化程序中返回例如cheapestSourcePrice作为产品的一部分,然后在Ember产品模型中添加cheapestSourcePrice并在模板中{{product.cheapestSourcePrice}}你不能{ {1}}控制服务器,然后像这样做。在将源设置为cheapesetSource之后再做一件事就是刷新之前不再需要了。如果你需要它来保持计算,你必须在模型上再添加一个属性然后设置他的insted示例

cheapestSource2:DS.attr()

这将允许它成为一个对象

product.set(&#34; cheapestSource2&#34;,source);

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

你调用的第一个属性就是这样调用的。

答案 2 :(得分:0)

如果你有时间尝试这个解决方案。 Program received signal SIGABRT, Aborted. 0x00007ffff6dc2428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54 54 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory. (gdb) bt #0 0x00007ffff6dc2428 in __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:54 #1 0x00007ffff6dc402a in __GI_abort () at abort.c:89 #2 0x00007ffff6e047ea in __libc_message (do_abort=do_abort@entry=2, fmt=fmt@entry=0x7ffff6f1d2e0 "*** Error in `%s': %s: 0x%s ***\n") at ../sysdeps/posix/libc_fatal.c:175 #3 0x00007ffff6e0ce0a in malloc_printerr (ar_ptr=<optimised out>, ptr=<optimised out>, str=0x7ffff6f1a0b2 "free(): invalid pointer", action=3) at malloc.c:5004 #4 _int_free (av=<optimised out>, p=<optimised out>, have_lock=0) at malloc.c:3865 #5 0x00007ffff6e1098c in __GI___libc_free (mem=<optimised out>) at malloc.c:2966 #6 0x0000000000401750 in __gnu_cxx::new_allocator<unsigned int>::deallocate(unsigned int*, unsigned long) () #7 0x000000000040171f in __gnu_cxx::__alloc_traits<std::allocator<unsigned int> >::deallocate(std::allocator<unsigned int>&, unsigned int*, unsigned long) () #8 0x00000000004016ae in std::__cxx11::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> >::_M_destroy(unsigned long) () #9 0x0000000000401624 in std::__cxx11::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> >::_M_dispose() () #10 0x00000000004015a3 in std::__cxx11::basic_string<unsigned int, std::char_traits<unsigned int>, std::allocator<unsigned int> >::~basic_string() () #11 0x000000000040156a in sf::String::~String() () #12 0x00007ffff7934f27 in (anonymous namespace)::ewmhSupported () at /usr/local/share/buildslave/debian-gcc-64/build/src/SFML/Window/Unix/WindowImplX11.cpp:253 #13 0x00007ffff7935da9 in sf::priv::WindowImplX11::WindowImplX11 (this=0x83c480, mode=..., title=..., style=7, settings=...) at /usr/local/share/buildslave/debian-gcc-64/build/src/SFML/Window/Unix/WindowImplX11.cpp:451 #14 0x00007ffff792f229 in sf::priv::WindowImpl::create (mode=..., title=..., style=7, settings=...) at /usr/local/share/buildslave/debian-gcc-64/build/src/SFML/Window/WindowImpl.cpp:71 #15 0x00007ffff792e7b3 in sf::Window::create (this=0x7fffffffdc20, mode=..., title=..., style=7, settings=...) at /usr/local/share/buildslave/debian-gcc-64/build/src/SFML/Window/Window.cpp:124 #16 0x00007ffff7ba796b in sf::RenderWindow::RenderWindow (this=0x7fffffffdc20, mode=..., title=..., style=7, settings=...) at /usr/local/share/buildslave/debian-gcc-64/build/src/SFML/Graphics/RenderWindow.cpp:45 #17 0x000000000040131e in main () 它返回Promise,因此您需要访问then方法中的结果并将其包装在DS.PromiseObject中,以便您可以像模板中的普通对象一样访问它。

this.get('priceSources')