@each 不更新计算的总和值
@each not updating computed sum value
在具有阵列模型的路线中,我需要一些可用的摘要统计信息。这些汇总统计数据需要根据输入到数字输入字段中的值进行更新。我试图通过在控制器中使用 @each 将这些设置为计算属性来实现这一点。
属性(creditTotal
和 costTotal
)在加载时计算,但在通过输入字段更新值时无法更新。不幸的是,他们需要更新,我不知道如何做到这一点。
诚然,我不是全职开发人员,所以我很感谢您提供的任何帮助和见解。
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>
试试这个:
// ./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');
})
});
使用“{”应该可以正常工作
我最终通过 很多 的反复试验找到了解决方案。虽然不是最优雅的,但这最终与 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()
目前这行不通,但我绝对希望将来会这样!
creditArray: computed('model.@each.creditCost', function(){
return this.get('model').mapBy('creditCost');
}),
creditTotal: computed.sum('creditArray')
I did stumble across an enhancement request discussing chaining of
these types of functions so it could become something like this.
this.get('model').mapBy('creditCost').sum()
Currently this does not work, but I definitely hope it will in the
future!
您必须区分 computed property macros (e.g. computed.sum) and native javascript array functions(例如 mapBy)。
以上是不可能的,因为javascript中没有sum
的功能,但是用reduce
.
可以很容易的实现
this.get('model').mapBy('creditCost').reduce((res, val) => res + val)
在具有阵列模型的路线中,我需要一些可用的摘要统计信息。这些汇总统计数据需要根据输入到数字输入字段中的值进行更新。我试图通过在控制器中使用 @each 将这些设置为计算属性来实现这一点。
属性(creditTotal
和 costTotal
)在加载时计算,但在通过输入字段更新值时无法更新。不幸的是,他们需要更新,我不知道如何做到这一点。
诚然,我不是全职开发人员,所以我很感谢您提供的任何帮助和见解。
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>
试试这个:
// ./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');
})
});
使用“{”应该可以正常工作
我最终通过 很多 的反复试验找到了解决方案。虽然不是最优雅的,但这最终与 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()
目前这行不通,但我绝对希望将来会这样!
creditArray: computed('model.@each.creditCost', function(){ return this.get('model').mapBy('creditCost'); }), creditTotal: computed.sum('creditArray')
I did stumble across an enhancement request discussing chaining of these types of functions so it could become something like this.
this.get('model').mapBy('creditCost').sum()
Currently this does not work, but I definitely hope it will in the future!
您必须区分 computed property macros (e.g. computed.sum) and native javascript array functions(例如 mapBy)。
以上是不可能的,因为javascript中没有sum
的功能,但是用reduce
.
this.get('model').mapBy('creditCost').reduce((res, val) => res + val)