mercredi 11 juillet 2018

Ember.js: Move controller computed properties from multiple models into a new model

Given a model substances containing an attribute measurements which is an array with objects. Every object is a measurement with some attributes like (int) value. Second model elements is a collection containing global data for all specific elements, such as average values.

I want every measurement to contain the respective element as an attribute, so I can pass it to components. E.g.:


    
    
    


I'm doing a single findAll(elements, {limit: 300}) once, so that every substance doesn't do dozens of requests to the jsonapi server.

I tried combining the two in model:substance, but model:elements is not available there (for obvious reasons). So I am doing this in the page controller like so:

export default Controller.extend({
    substance       : computed.alias('model.substance'),
    measurements    : computed.alias('substance.measurements'),
    elements        : computed.alias('model.elements'),
    contents        : computed('{elements,measurements}.[]', function() {
        if (!this.get('elements')) return null
        if (!this.get('measurements')) return null
        return this.get('measurements').map(m => {
            const element = this.get('elements').find(detail => detail.id == m.id)
            if (element) set(m, 'element', element)
            return m
        })
    }),

    // More calculations w/ `utils` here based on `contents`

This works, but there are some problems. First (1), the contents:computed fires 3 times.

  1. When it is referenced is the template;
  2. when model.substance is loaded;
  3. when model.elements is loaded.

Not a big problem because the first two times, it will return null.

Second (2), all references to a specific measurement in the template (e.g.: ) will literally display undefined until everything is calculated in the 3rd iteration. I would like it to display nothing ('') until it is loaded.

However, my final goal is to be able to pass substance (with the combined measurements + elements) to a shopping-cart-like service so you can compose your own list of substances, after which it can make calculations and show a summary, independent.

How do I move these controller:substance computations to a self-contained item (model?) that can be passed around to services (3), given that I cannot do this inside model:substance?

I cannot reference the controller:substance from a service, because controllers are singeltons.




Aucun commentaire:

Enregistrer un commentaire