下面的脚本使用ng-repeat
显示商店购物车。对于数组中的每个元素,它显示项目名称,其数量和小计(product.price * product.quantity
)。
计算重复元素总价的最简单方法是什么?
<table>
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<tr ng-repeat="product in cart.products">
<td>{{product.name}}</td>
<td>{{product.quantity}}</td>
<td>{{product.price * product.quantity}} €</td>
</tr>
<tr>
<td></td>
<td>Total :</td>
<td></td> <!-- Here is the total value of my cart -->
</tr>
</table>
答案 0 :(得分:143)
在模板中
<td>Total: {{ getTotal() }}</td>
在控制器
中$scope.getTotal = function(){
var total = 0;
for(var i = 0; i < $scope.cart.products.length; i++){
var product = $scope.cart.products[i];
total += (product.price * product.quantity);
}
return total;
}
答案 1 :(得分:57)
这也适用于过滤器和普通列表。首先要为列表中的所有值的总和创建一个新过滤器,并给出总量的总和的解决方案。 在详细代码中,请检查fiddler link。
angular.module("sampleApp", [])
.filter('sumOfValue', function () {
return function (data, key) {
if (angular.isUndefined(data) || angular.isUndefined(key))
return 0;
var sum = 0;
angular.forEach(data,function(value){
sum = sum + parseInt(value[key], 10);
});
return sum;
}
}).filter('totalSumPriceQty', function () {
return function (data, key1, key2) {
if (angular.isUndefined(data) || angular.isUndefined(key1) || angular.isUndefined(key2))
return 0;
var sum = 0;
angular.forEach(data,function(value){
sum = sum + (parseInt(value[key1], 10) * parseInt(value[key2], 10));
});
return sum;
}
}).controller("sampleController", function ($scope) {
$scope.items = [
{"id": 1,"details": "test11","quantity": 2,"price": 100},
{"id": 2,"details": "test12","quantity": 5,"price": 120},
{"id": 3,"details": "test3","quantity": 6,"price": 170},
{"id": 4,"details": "test4","quantity": 8,"price": 70}
];
});
<div ng-app="sampleApp">
<div ng-controller="sampleController">
<div class="col-md-12 col-lg-12 col-sm-12 col-xsml-12">
<label>Search</label>
<input type="text" class="form-control" ng-model="searchFilter" />
</div>
<div class="col-md-12 col-lg-12 col-sm-12 col-xsml-12">
<div class="col-md-2 col-lg-2 col-sm-2 col-xsml-2">
<h4>Id</h4>
</div>
<div class="col-md-4 col-lg-4 col-sm-4 col-xsml-4">
<h4>Details</h4>
</div>
<div class="col-md-2 col-lg-2 col-sm-2 col-xsml-2 text-right">
<h4>Quantity</h4>
</div>
<div class="col-md-2 col-lg-2 col-sm-2 col-xsml-2 text-right">
<h4>Price</h4>
</div>
<div class="col-md-2 col-lg-2 col-sm-2 col-xsml-2 text-right">
<h4>Total</h4>
</div>
<div ng-repeat="item in resultValue=(items | filter:{'details':searchFilter})">
<div class="col-md-2 col-lg-2 col-sm-2 col-xsml-2">{{item.id}}</div>
<div class="col-md-4 col-lg-4 col-sm-4 col-xsml-4">{{item.details}}</div>
<div class="col-md-2 col-lg-2 col-sm-2 col-xsml-2 text-right">{{item.quantity}}</div>
<div class="col-md-2 col-lg-2 col-sm-2 col-xsml-2 text-right">{{item.price}}</div>
<div class="col-md-2 col-lg-2 col-sm-2 col-xsml-2 text-right">{{item.quantity * item.price}}</div>
</div>
<div colspan='3' class="col-md-8 col-lg-8 col-sm-8 col-xsml-8 text-right">
<h4>{{resultValue | sumOfValue:'quantity'}}</h4>
</div>
<div class="col-md-2 col-lg-2 col-sm-2 col-xsml-2 text-right">
<h4>{{resultValue | sumOfValue:'price'}}</h4>
</div>
<div class="col-md-2 col-lg-2 col-sm-2 col-xsml-2 text-right">
<h4>{{resultValue | totalSumPriceQty:'quantity':'price'}}</h4>
</div>
</div>
</div>
</div>
检查此Fiddle Link
答案 2 :(得分:40)
很久以前就意识到了这个问题,但想要发布不同的方法......
使用ng-init
计算总数。这样,您不必迭代HTML并在控制器中迭代。在这种情况下,我认为这是一个更简洁/更简单的解决方案。 (如果计数逻辑更复杂,我肯定会建议将逻辑移动到控制器或服务中。)
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<tr ng-repeat="product in cart.products">
<td>{{product.name}}</td>
<td>{{product.quantity}}</td>
<td ng-init="itemTotal = product.price * product.quantity; controller.Total = controller.Total + itemTotal">{{itemTotal}} €</td>
</tr>
<tr>
<td></td>
<td>Total :</td>
<td>{{ controller.Total }}</td> // Here is the total value of my cart
</tr>
当然,在您的控制器中,只需定义/初始化您的Total
字段:
// random controller snippet
function yourController($scope..., blah) {
var vm = this;
vm.Total = 0;
}
答案 3 :(得分:17)
您可以计算ng-repeat
内部的总数:
<tbody ng-init="total = 0">
<tr ng-repeat="product in products">
<td>{{ product.name }}</td>
<td>{{ product.quantity }}</td>
<td ng-init="$parent.total = $parent.total + (product.price * product.quantity)">${{ product.price * product.quantity }}</td>
</tr>
<tr>
<td>Total</td>
<td></td>
<td>${{ total }}</td>
</tr>
</tbody>
在此处查看结果:http://plnkr.co/edit/Gb8XiCf2RWiozFI3xWzp?p=preview
如果是自动更新结果:http://plnkr.co/edit/QSxYbgjDjkuSH2s5JBPf?p=preview(谢谢 - VicJordan)
答案 4 :(得分:9)
甜蜜而简单的自定义过滤器:
(但只与简单的值之和有关,而不是和产品相关,我已经编制了sumProduct
过滤器并将其作为编辑添加到此帖子中。)
angular.module('myApp', [])
.filter('total', function () {
return function (input, property) {
var i = input instanceof Array ? input.length : 0;
// if property is not defined, returns length of array
// if array has zero length or if it is not an array, return zero
if (typeof property === 'undefined' || i === 0) {
return i;
// test if property is number so it can be counted
} else if (isNaN(input[0][property])) {
throw 'filter total can count only numeric values';
// finaly, do the counting and return total
} else {
var total = 0;
while (i--)
total += input[i][property];
return total;
}
};
})
这是sumProduct
过滤器,它接受任意数量的参数。作为参数,它接受来自输入数据的属性的名称,并且它可以处理嵌套属性(嵌套标记为点:property.nested
);
这里是JS Fiddle和代码
angular.module('myApp', [])
.filter('sumProduct', function() {
return function (input) {
var i = input instanceof Array ? input.length : 0;
var a = arguments.length;
if (a === 1 || i === 0)
return i;
var keys = [];
while (a-- > 1) {
var key = arguments[a].split('.');
var property = getNestedPropertyByKey(input[0], key);
if (isNaN(property))
throw 'filter sumProduct can count only numeric values';
keys.push(key);
}
var total = 0;
while (i--) {
var product = 1;
for (var k = 0; k < keys.length; k++)
product *= getNestedPropertyByKey(input[i], keys[k]);
total += product;
}
return total;
function getNestedPropertyByKey(data, key) {
for (var j = 0; j < key.length; j++)
data = data[key[j]];
return data;
}
}
})
答案 5 :(得分:4)
简单解决方案
这是一个简单的解决方案。无需额外的循环。
HTML部分
<table ng-init="ResetTotalAmt()">
<tr>
<th>Product</th>
<th>Quantity</th>
<th>Price</th>
</tr>
<tr ng-repeat="product in cart.products">
<td ng-init="CalculateSum(product)">{{product.name}}</td>
<td>{{product.quantity}}</td>
<td>{{product.price * product.quantity}} €</td>
</tr>
<tr>
<td></td>
<td>Total :</td>
<td>{{cart.TotalAmt}}</td> // Here is the total value of my cart
</tr>
</table>
脚本部分
$scope.cart.TotalAmt = 0;
$scope.CalculateSum= function (product) {
$scope.cart.TotalAmt += (product.price * product.quantity);
}
//It is enough to Write code $scope.cart.TotalAmt =0; in the function where the cart.products get allocated value.
$scope.ResetTotalAmt = function (product) {
$scope.cart.TotalAmt =0;
}
答案 6 :(得分:3)
这是一种使用ng-repeat和ng-init来聚合所有值并使用item.total属性扩展模型的简单方法。
<table>
<tr ng-repeat="item in items" ng-init="setTotals(item)">
<td>{{item.name}}</td>
<td>{{item.quantity}}</td>
<td>{{item.unitCost | number:2}}</td>
<td>{{item.total | number:2}}</td>
</tr>
<tr class="bg-warning">
<td>Totals</td>
<td>{{invoiceCount}}</td>
<td></td>
<td>{{invoiceTotal | number:2}}</td>
</tr>
</table>
ngInit指令调用每个项目的set total函数。 控制器中的setTotals函数计算每个项目总数。它还使用invoiceCount和invoiceTotal范围变量来聚合(总和)所有项目的数量和总计。
$scope.setTotals = function(item){
if (item){
item.total = item.quantity * item.unitCost;
$scope.invoiceCount += item.quantity;
$scope.invoiceTotal += item.total;
}
}
有关更多信息和演示,请查看此链接:
http://www.ozkary.com/2015/06/angularjs-calculate-totals-using.html
答案 7 :(得分:3)
另一种解决方法,从Vaclav的answer扩展到解决这个特定的计算 - 即每行的计算。
.filter('total', function () {
return function (input, property) {
var i = input instanceof Array ? input.length : 0;
if (typeof property === 'undefined' || i === 0) {
return i;
} else if (typeof property === 'function') {
var total = 0;
while (i--)
total += property(input[i]);
return total;
} else if (isNaN(input[0][property])) {
throw 'filter total can count only numeric values';
} else {
var total = 0;
while (i--)
total += input[i][property];
return total;
}
};
})
要通过计算执行此操作,只需在范围中添加计算功能,例如
$scope.calcItemTotal = function(v) { return v.price*v.quantity; };
您可以在HTML代码中使用{{ datas|total:calcItemTotal|currency }}
。这样做的好处是不会为每个摘要调用,因为它使用过滤器,可用于简单或复杂的总计。
答案 8 :(得分:2)
I prefer elegant solutions
In Template
<td>Total: {{ totalSum }}</td>
In Controller
$scope.totalSum = Object.keys(cart.products).map(function(k){
return +cart.products[k].price;
}).reduce(function(a,b){ return a + b },0);
If you're using ES2015 (aka ES6)
$scope.totalSum = Object.keys(cart.products)
.map(k => +cart.products[k].price)
.reduce((a, b) => a + b);
答案 9 :(得分:2)
您可以使用自定义Angular过滤器,该过滤器将数据集对象数组和每个对象中的键求和。然后,过滤器可以返回总和:
.filter('sumColumn', function(){
return function(dataSet, columnToSum){
let sum = 0;
for(let i = 0; i < dataSet.length; i++){
sum += parseFloat(dataSet[i][columnToSum]) || 0;
}
return sum;
};
})
然后在表格中汇总可以使用的列:
<th>{{ dataSet | sumColumn: 'keyInObjectToSum' }}</th>
答案 10 :(得分:1)
这是我解决这个问题的方法:
<td>Total: {{ calculateTotal() }}</td>
脚本
$scope.calculateVAT = function () {
return $scope.cart.products.reduce((accumulator, currentValue) => accumulator + (currentValue.price * currentValue.quantity), 0);
};
reduce将对产品阵列中的每个产品执行。 累加器是总累计量,currentValue是数组的当前元素,最后一个是初始值
答案 11 :(得分:1)
您可以尝试使用angular js服务,它对我有用。.给出下面的代码段
控制器代码:
$scope.total = 0;
var aCart = new CartService();
$scope.addItemToCart = function (product) {
aCart.addCartTotal(product.Price);
};
$scope.showCart = function () {
$scope.total = aCart.getCartTotal();
};
服务代码:
app.service("CartService", function () {
Total = [];
Total.length = 0;
return function () {
this.addCartTotal = function (inTotal) {
Total.push( inTotal);
}
this.getCartTotal = function () {
var sum = 0;
for (var i = 0; i < Total.length; i++) {
sum += parseInt(Total[i], 10);
}
return sum;
}
};
});
答案 12 :(得分:0)
采取Vaclav的答案并使其更像Angular:
angular.module('myApp').filter('total', ['$parse', function ($parse) {
return function (input, property) {
var i = input instanceof Array ? input.length : 0,
p = $parse(property);
if (typeof property === 'undefined' || i === 0) {
return i;
} else if (isNaN(p(input[0]))) {
throw 'filter total can count only numeric values';
} else {
var total = 0;
while (i--)
total += p(input[i]);
return total;
}
};
}]);
这使您甚至可以访问嵌套和数组数据:
{{data | total:'values[0].value'}}
答案 13 :(得分:0)
我对RajaShilpa的答案进行了一些扩展。您可以使用以下语法:
{{object | sumOfTwoValues:'quantity':'products.productWeight'}}
以便您可以访问对象的子对象。以下是过滤器的代码:
.filter('sumOfTwoValues', function () {
return function (data, key1, key2) {
if (typeof (data) === 'undefined' || typeof (key1) === 'undefined' || typeof (key2) === 'undefined') {
return 0;
}
var keyObjects1 = key1.split('.');
var keyObjects2 = key2.split('.');
var sum = 0;
for (i = 0; i < data.length; i++) {
var value1 = data[i];
var value2 = data[i];
for (j = 0; j < keyObjects1.length; j++) {
value1 = value1[keyObjects1[j]];
}
for (k = 0; k < keyObjects2.length; k++) {
value2 = value2[keyObjects2[k]];
}
sum = sum + (value1 * value2);
}
return sum;
}
});
答案 14 :(得分:0)
在html中
<b class="text-primary">Total Amount: ${{ data.allTicketsTotalPrice() }}</b>
在javascript中
app.controller('myController', function ($http) {
var vm = this;
vm.allTicketsTotalPrice = function () {
var totalPrice = 0;
angular.forEach(vm.ticketTotalPrice, function (value, key) {
totalPrice += parseFloat(value);
});
return totalPrice.toFixed(2);
};
});
答案 15 :(得分:0)
Huy Nguyen的回答几乎就在那里。要使其工作,请添加:
ng-repeat="_ in [ products ]"
...到ng-init的行。该列表始终只有一个项目,因此Angular将重复该块一次。
使用过滤的Zybnek演示可以通过添加:
来实现ng-repeat="_ in [ [ products, search ] ]"
答案 16 :(得分:0)
**Angular 6: Grand Total**
**<h2 align="center">Usage Details Of {{profile$.firstName}}</h2>
<table align ="center">
<tr>
<th>Call Usage</th>
<th>Data Usage</th>
<th>SMS Usage</th>
<th>Total Bill</th>
</tr>
<tr>
<tr *ngFor="let user of bills$">
<td>{{ user.callUsage}}</td>
<td>{{ user.dataUsage }}</td>
<td>{{ user.smsUsage }}</td>
<td>{{user.callUsage *2 + user.dataUsage *1 + user.smsUsage *1}}</td>
</tr>
<tr>
<th> </th>
<th>Grand Total</th>
<th></th>
<td>{{total( bills$)}}</td>
</tr>
</table>**
**Controller:**
total(bills) {
var total = 0;
bills.forEach(element => {
total = total + (element.callUsage * 2 + element.dataUsage * 1 + element.smsUsage * 1);
});
return total;
}
答案 17 :(得分:0)
这是我的解决方法
<div ng-controller="MainCtrl as mc">
<ul>
<li ng-repeat="n in [1,2,3,4]" ng-init="mc.sum = ($first ? 0 : mc.sum) + n">{{n}}</li>
<li>sum : {{mc.sum}}</li>
</ul>
</div>
它要求您将控制器的名称添加为Controller as SomeName
,以便我们可以在其中缓存变量(这真的需要吗?我不熟悉使用$ parent,所以不知道)
然后为每个重复添加ng-init"SomeName.SumVariable = ($first ? 0 : SomeName.SumVariable) + repeatValue"
$first
首先检查它,然后将其重置为零,否则它将继续汇总值
答案 18 :(得分:-2)
在阅读完这里的所有答案后 - 如何汇总分组信息,我决定跳过这一切,只是加载了一个SQL javascript库。我使用的是alasql,是的,加载时间需要几秒钟,但在编码和调试时节省了无数的时间,现在要分组和sum()我只是使用,
$scope.bySchool = alasql('SELECT School, SUM(Cost) AS Cost from ? GROUP BY School',[restResults]);
我知道这听起来像是对angular / js有点咆哮,但是真正的SQL在30多年前解决了这个问题,我们不应该在浏览器中重新发明它。