2017-02-18 37 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}} 

Как я пошел бы о настройке самого дешевого источника энергии? Я полагаю, я должен был бы сделать что-то вроде этого:

// 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, а затем вызывая firstObject отсортированныхPrices в шаблоне. Скоро отредактирует этот пост с фактическим решением.

Потребовались возрасты, чтобы проверить, потому что я не понимал, что комментирование блоков руля разбивает визуализацию html внутри них. Примечание для себя ...


EDIT: Это сделал:

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

Это можно сделать на контроллере, где вам нужно использовать cheapSource.

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 как часть продукта в моем пользовательском сериализаторе то в модели продукта Эмбера просто добавьте cheapestSourcePrice и в шаблоне {{product.cheapestSourcePrice} } Вы надеваете t want ember to do heavy lifting like this but if you don t управлять сервером, тогда сделайте это так. И еще одна вещь после этого устанавливает источник для cheapesetSource, вычисленный уже не до обновления. Если вам это нужно, чтобы остаться вычислен необходимо добавить еще одно свойство на модели затем установить его InstEd пример

cheapestSource2: DS.attr()

это позволит ему быть объектом

продукт. set ("cheapSource2", источник);

, а затем в шаблоне {{product.cheapestSource}} {{}} product.cheapestSource2.price

первое свойство вы называете это там так вычислен называется.

+0

Я читаю это [отношения, как обещает] (https://guides.emberjs.com/v2.11.0/models/relationships/#toc_relationships-as-promises) руководство. можем ли мы получить к нему доступ прямо так, как вы делаете? если возможно, объясните в своем ответе. Просто для моего обучения. спасибо. И также зависимый ключ 'priceSources. @ each.price' может быть полезен. Я удалю свой комментарий после того, как вы прочитали – kumkanillam

+0

Я сделал это на контроллере, теперь я понимаю, почему вы задаете этот вопрос, он сделал это в модели thx для проверки. –

+0

@ Sedad.Kosovac К сожалению, объект priceSource не отображается (в Ember Inspector). Я не получаю ошибок. Я попробовал 'return this.get ('priceSources'). Get ('firstObject')', также попробовал 'return this.get ('priceSources.firstObject')', но нет. Поскольку мне нужны источники, отсортированные в любом случае, лучший способ получить самый дешевый вариант - это, вероятно, сначала отсортировать, а затем извлечь firstObject в вычисленное свойство sortedSources. –

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 (...), а затем не является функцией'. Я думаю, что это было бы хорошим решением, потому что я хотел бы иметь дешевое в качестве вычисленного свойства после сортировки источников. Например, sources => 'function, я мог бы просто вернуть sources.firstObject, sources.get ('firstObject'), sources [0] или что там есть правильный синтаксис. –

+0

Вы можете определить его в модели и по умолчанию' priceSources: DS. hasMany ('price-source', {async: true}) '. если свойство async true, то оно возвращает Promise, поэтому' then' является вещью, и если его false возвращает DS.ManyArray, значит, 'then' не является тем, что вы я получаю эту ошибку. Я не разработал какой-либо пример, я просто протащил эту [ember igniter article для загрузки] (ht tps: //emberigniter.com/guide-promises-computed-properties/) @VilleLehtinen – kumkanillam