【问题标题】:@each not updating computed sum value@each 不更新计算的总和值
【发布时间】:2018-06-12 15:05:25
【问题描述】:

在具有数组模型的路线中,我需要一些可用的汇总统计信息。这些汇总统计信息需要根据输入到数字输入字段中的值进行更新。我试图通过在控制器中使用 @each 将这些设置为计算属性来实现这一点。

属性(creditTotalcostTotal)在加载时计算,但在通过输入字段更新值时无法更新。不幸的是,他们需要更新,我不知道如何做到这一点。

诚然,我不是一名全职开发人员,因此我非常感谢您提供的任何帮助和见解。

0640PST 03Jan2018:我还将它放在 GitHub 存储库 (https://github.com/knu2xs/arcgis-credit-calculator) 中,希望能让任何有足够时间的人更轻松地仔细研究它。

这里是相关文件,从控制器开始。

// ./app/controllers/index.js

import Controller from '@ember/controller';
import { computed } from '@ember/object';

export default Controller.extend({
  creditTotal: computed.sum('model.@each.creditCost', function(){
    return this.get('model').mapBy('creditCost');
  }),
  costTotal: computed.sum('model.@each.cost', function(){
    return this.get('model').mapBy('cost');
  })
});

接下来,被引用的模型。

// ./app/models/credit-object.js

import DS from 'ember-data';
import { computed } from '@ember/object';

const _creditCost = 0.1;

export default DS.Model.extend({

  name: DS.attr('string'),
  description: DS.attr('string'),
  creditRate: DS.attr('number'),
  unitRate: DS.attr('number'),
  units: DS.attr('number', { defaultValue: 0 }),

  rate: computed('creditRate', 'unitRate', function(){
    return Number(this.get('creditRate')) / Number(this.get('unitRate'));
  }),
  creditCost: computed('rate', 'units', function(){
    return this.get('rate') * this.get('units');
  }),
  cost: computed('creditCost', function(){
    return this.get('creditCost') * _creditCost;
  }),
});

还有路线。

// ./app/routes/index.js

import Route from '@ember/routing/route';

export default Route.extend({
  model() {
    return this.get('store').findAll('credit-object');
  }
});

最后是模板,希望它有点意义。

<table class="table table-striped table-sm">
  <thead>
  <tr>
    <th scope="col">Name</th>
    <th scope="col">Credit Rate</th>
    <th scope="col">Unit Count</th>
    <th scope="col">Credit Count</th>
    <th scope="col">Cost</th>
  </tr>
  </thead>
  <tbody>
  {{#each model as |creditObject|}}
    <tr>
      <td>{{creditObject.name}}</td>
      <td>{{creditObject.rate}}</td>
      <td>{{input type='number' value=creditObject.units}}</td>
      <td>{{format-floating-point creditObject.creditCost}}</td>
      <td>{{format-currency creditObject.cost}}</td>
    </tr>
  {{/each}}
  <tr class="table-primary">
    <td>Total</td>
    <td></td>
    <td></td>
    <td>{{format-floating-point creditTotal}}</td>
    <td>{{format-currency costTotal}}</td>
  </tr>
  </tbody>
</table>

【问题讨论】:

  • 尝试在计算属性中添加'model.@each.creditCost' (computed.sum(here, '...', func...)。还请出示您的路线的模型挂钩!
  • 如果我没记错computed.sum() 只接受一个参数,即依赖键。见docs
  • @Jeff,正如你提到的,我从直接引用属性开始,但是这些属性也是自己计算的,我不知道这是否是问题的根源,所以我在看实际财产被改变。实际上,几分钟前我删除了总和进行测试,有趣的是,它在 UI 中显示了完整的数组,当引用 creditCostcost 时,受影响的值会发生变化。因此,问题似乎出在sum,而不是计算属性监视另一个计算属性。
  • @ykaragol,这是我开始的地方,刚刚尝试了似乎打算以这种方式实现的方式。 this.get('model').sum('creditCost') 不幸的是,这样做时,我收到一个错误,TypeError: this.get(...).sum is not a function。我在正确的轨道上吗?这种方法对我来说合乎逻辑,但似乎不起作用。有什么想法吗?

标签: ember.js computed-properties


【解决方案1】:

我最终通过大量的反复试验找到了解决方案。虽然不是最优雅的,但最终与 Ember.js 版本 2.18 一起使用。

creditArray: computed('model.@each.creditCost', function(){
  return this.get('model').mapBy('creditCost');
}),
creditTotal: computed.sum('creditArray')

我确实偶然发现了一个增强请求,讨论了这些类型的函数的链接,因此它可以变成这样。

this.get('model').mapBy('creditCost').sum()

目前这不起作用,但我绝对希望将来会这样做!

【讨论】:

    【解决方案2】:
    creditArray: computed('model.@each.creditCost', function(){
      return this.get('model').mapBy('creditCost');
    }),
    creditTotal: computed.sum('creditArray')
    

    我确实偶然发现了一个讨论链接的增强请求 这些类型的函数,所以它可以变成这样。

    this.get('model').mapBy('creditCost').sum()

    目前这不起作用,但我绝对希望它会在 未来!

    您必须区分computed property macros(例如computed.sum)和native javascript array functions(例如mapBy)。 以上是不可能的,因为javascript中没有sum函数可用,但是可以用reduce轻松实现。

    this.get('model').mapBy('creditCost').reduce((res, val) => res + val)
    

    【讨论】:

      【解决方案3】:

      试试这个:

      // ./app/controllers/index.js
      
      import Controller from '@ember/controller';
      import { computed } from '@ember/object';
      
      export default Controller.extend({
        creditTotal: computed.sum('model.@each.{units}', function(){
          return this.get('model').mapBy('creditCost');
        }),
        costTotal: computed.sum('model.@each.{units}', function(){
          return this.get('model').mapBy('cost');
        })
      });
      

      使用“{”应该可以正常工作

      【讨论】:

      • 我试过这个,但它抛出了一个错误。正如您在上面的讨论中看到的那样,通过更多的试验和错误,这似乎是我在使用sum 函数的方式上做错的事情,但还没有完全弄清楚......跨度>
      猜你喜欢
      • 1970-01-01
      • 2014-07-21
      • 2017-05-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-06-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多