【问题标题】:Ember.js: Move controller computed properties from multiple models into a new modelEmber.js:将控制器计算属性从多个模型移动到新模型中
【发布时间】:2018-07-11 14:08:03
【问题描述】:

给定一个模型substances,其中包含一个属性measurements,它是一个包含对象的数组。每个对象都是具有某些属性的度量,例如(int) value。 第二个模型elements 是一个集合,其中包含所有特定元素的全局数据,例如平均值。

我希望每个度量都包含相应的元素作为属性,所以我可以将它传递给组件。例如:

{{#each contents as |m|}}
    {{some-graph m}}
    {{some-chart m}}
    {{some-data m}}
{{/each}}

我只做一次findAll(elements, {limit: 300, reload: false}),这样每个实体就不会向jsonapi服务器发出几十个请求。所以route:substance的模型是:

model(params) {
    return {
        substance   : this.store.findRecord('substance', params.substance_id),
        elements    : this.store.findAll('element', {limit: 300, reload: false}})
    }
},

我尝试在model:substance 中将两者结合起来,但model:elements 在那里不可用(原因很明显)。所以我在controller:substance 这样做:

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`

这可行,但存在一些问题。首先 (1),contents:computed 触发 3 次。

  1. 引用的时候是模板;
  2. model.substance被加载时;
  3. model.elements被加载时。

不是大问题(开销),因为前两次,它将return null

第二 (2),模板中对特定测量的所有引用(例如:{{contents.oxigen.value}})将按字面意思显示undefined,直到在第三次computed 迭代中计算出所有内容。我希望它在加载之前不显示任何内容 ('')。

但是,我的最终目标是能够将substance(与measurements + elements 组合在一起)传递给类似购物车的service,这样您就可以编写自己的物质清单,之后它可以进行计算并显示摘要,与您当前的路线/控制器无关。

我如何将这些 controller:substance 计算移动到可以传递给服务的独立项目(模型?) (3),因为我无法在 model:substance 内部执行此操作?

我不能从service 中引用这个controller:substance,因为控制器是单例的。

【问题讨论】:

  • 是否可以选择使用 loadSubstanceContent() 函数创建服务,然后在模型挂钩中调用该函数?然后这个函数可以加载物质模型、元素,一起计算它们并返回结果。该服务还可以缓存元素甚至计算结果。该服务也可以在组件中使用,并且通过缓存将不需要重新计算。

标签: ember.js service model controller json-api


【解决方案1】:

如果您需要在显示任何数据之前解析所有数据,您可以使用RSVP.hash,它只有在两个 Promise 都已解析时才会解析。

import { hash } from 'rsvp';
model(params) {
    return hash({
        substance   : this.store.findRecord('substance', params.substance_id),
        elements    : this.store.findAll('element', {limit: 300, reload: false}})
    });
}

现在,内容将只计算一次,因为控制器在两者都解决之前不会加载。 不能取消定义测量值,因为数据已经加载。

【讨论】:

  • +1 用于解释hash。然而,这样一来,一切仍然取决于controller。我想在不同的页面(例如不同的控制器)上使用相同的计算值。
猜你喜欢
  • 2013-04-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多