後端返回扁平商品陣列,前端需按 sstype(店鋪類型/名稱)分組渲染,類似淘寶/京東購物車「店鋪為單位,商品列表內嵌」結構。
app.controller('CartCtrl', ['$scope', 'GoodsSvc', function($scope, GoodsSvc) {
$scope.goods = GoodsSvc.getGoods(); // 原始扁平陣列
// 1. 按店鋪分組
$scope.shops = {};
$scope.goods.forEach(function(item) {
var key = item.sstype; // 或 item.shopId 更穩健
if (!$scope.shops[key]) {
$scope.shops[key] = {
name: key,
items: [],
total: 0
};
}
$scope.shops[key].items.push(item);
$scope.shops[key].total += item.price * item.count;
});
// 2. 轉為陣列便於 ng-repeat 排序
$scope.shopList = Object.keys($scope.shops).map(function(k) {
return $scope.shops[k];
});
// 可選:按店鋪名/總價排序
$scope.shopList.sort(function(a, b) { return a.name.localeCompare(b.name); });
}]);
<div ng-repeat="shop in shopList">
<h3>{{ shop.name }} <span>共 {{ shop.items.length }} 件,小計 ¥{{ shop.total }}</span></h3>
<div ng-repeat="item in shop.items">
<img ng-src="{{ item.image_file }}">
<span>{{ item.name }}</span>
<span>¥{{ item.price }} x {{ item.count }}</span>
<button ng-click="remove(item)">刪除</button>
</div>
</div>
groupBy filter(angular-filter 庫):模板層分組,但大數據集性能較差。ng-repeat="item in shop.items track by item.id" 避免 DOM 重建閃爍。ui-virtual-scroll。ng-repeat="item in goods | groupBy: 'sstype'" 導致每次 $digest 重新分組,效率低。shopId 分組,顯示名稱。CartService 統一管理狀態。總結:控制器預處理扁平數據為樹狀結構 是 AngularJS 1.x 典型模式,清晰分離關注點,模板保持簡潔。Angular 2+ 則建議用 Pipe 或 Component 內計算屬性實現同樣邏輯。