编辑:感谢SimonSchüpbach,我能够通过更改模板来解决问题。请参阅最终解决方案。
让我们在前言中说我们是Angular的软中间人的初学者。
在我们的一个项目中,我们使用angularjs 1.4.x和ng-cart(https://github.com/snapjay/ngCart)。它工作得很好,但后来我们遇到了客户的要求,产生了新的奇怪问题。
我们将fsCounter作为指令添加到购物车页面,以便用户可以添加或删除商品。这一切都很好,但用户也可以选择从购物车视图中删除项目。删除按预期工作但它似乎影响了取代它的项目的范围。
让我说清楚一下: 假设我们的购物车页面中有2个产品,它会显示类似的内容
Product_1 {price} {counter} {total} delete_btn
Product_2 {price} {counter} {total} delete_btn
每个fsCounter都是自己的范围
return {
restrict: "A",
scope: {
value: "=value",
index: "=index"
},
link: //other logic
然而,当我们在视觉上和指令中删除第一个项目时,数据似乎发生了变化。所以我们的第二行现在将继承第一行的计数器。 指令的数据如下:
Product_1:
itemId:3,
quantity:2,
{other data}
Product_2:
itemId:8,
quantity:5,
{other data}
但是一旦我们删除第一个指令(我们获取范围,删除DOM元素,销毁范围),第二个指令现在将拥有这些数据:
Product_2:
itemId:3,
quantity:2,
{other data}
以下是模板代码:
<div class="unItem" ng-repeat="item in ngCart.getCart().items track by $index">
<div class="photo"><img src="{[{ item.getImage() }]}" alt=""></div>
<div class="details">
<h3>{[{ item.getName() }]} <span>{[{ item.getPrice() | currency:$}]}</span></h3>
<md-select ng-model="attributes" placeholder="Attribut" class="select-attribut" ng-show="item.hasAttributes()" ng-change="item.updateSelected(attributes)">
<md-option ng-repeat="attr in item.getAttributes()" ng-selected="attr == item.getSelected()" ng-value="attr">{[{ attr }]}</md-option>
</md-select>
</div>
<div class="quantity">
<div fs-counter-dynamic value="itemQuantity"
data-min="1"
data-max="999"
data-step="1"
data-addclass="add-quantity"
data-width="130px"
data-itemid="{[{ item.getId() }]}"
data-editable
ng-model="itemQuantity"
name="quantity" id="quantity-{[{ item.getId() }]}",
index="{[{ item.getId() }]}"
></div>
</div>
<div class="total">Total : {[{ item.getTotal() | currency }]}</div>
<div class="delete"><a ng-click="ngCart.removeItemById(item.getId());"></a></div>
</div>
这是正常行为吗?有没有办法强制指令保留自己的数据?根据我的理解,每个指令都有自己的范围,所以我认为发生的是,当我们删除第一个时,它会将数据保存在某种类型的数组中,表示“指令1数据是:”,当我们删除第一个指令,第二个指令成为第一个指令。
所以基本上,我们做错了什么或者无论如何重新映射数据?
希望它足够清楚, 谢谢!
编辑:添加了HTML代码
Edit2:答案: 新的FsCounter模板如下所示:
<div fs-counter-dynamic value="item._quantity"
data-min="1"
data-max="999"
data-step="1"
data-addclass="add-quantity"
data-width="130px"
data-itemid="{[{ item.getId() }]}"
data-editable
ng-model="item._quantity"
name="quantity" id="quantity{[{ item.getId() }]}"
></div>
答案 0 :(得分:2)
您知道ng-repeat
,那么您没有这样的问题
<div ng-repeat="product in products">
<fs-counter index="product.index" value="product.value"></fs-counter>
</div>
并在您的控制器中
$scope.products = [
{index:1, value:"Cola"},
{index:2,,value:"Fanta"}
]
删除您必须执行的元素
$scope.products.splice(0,1);
修改强>
我建议在ng-repeat
内使用的项目中保存所有必要的数据。您的问题是,您将数组中的数据与$scope
中的其他数据混合在一起。您的指令可能会发生$watch
次更改,但如果您使用ng-repeat
进行更改,则所有内容都会自动完成。
$scope.products = [
{index:1, name:"Cola", price:1.50, image:"your/path.png", attributes:{...}},
{index:2, name:"Fanta", price:1.40, image:"your/path.png"}
]
然后在你的HTML中
<div class="unItem" ng-repeat="item in ngCart.products track by $index">
<div class="photo"><img ng-src="item.image" alt=""></div>
<div class="details">
<h3>{{item.name}} <span>{{item.price | currency}}</span></h3>
</div>
<div class="quantity">
<div fs-counter-dynamic value="item.quantity"
data-min="1"
data-max="999"
data-step="1"
data-addclass="add-quantity"
data-width="130px"
data-itemid="item.index"
data-editable
ng-model="item.quantity"
name="quantity" id="{{'quantity-' + $index}}",
index="item.index"
></div>
</div>
<div class="total">Total : {{ item.price * item.quantity | currency }}</div>
<div class="delete"><a ng-click="ngCart.removeItemById(item.index);"></a></div>
</div>