为什么推送对象到数组覆盖/更新现有的和相似的对象?

时间:2015-06-09 13:53:30

标签: javascript angularjs

我的javascript / angular代码表现与我的预期相反,我无法弄清楚原因。我有一个角度服务,定义了两种获取和设置项目的方法

app.factory('orderItems',['Restangular','$mdDialog',function(Restangular,$mdDialog){
    var orderItems = [];

    return{
        getOrderItems: function(){
            return orderItems
        },


        setOrderItems: function(item,fillings){
            ...
            orderItems.push(item)
            ...

        }, ...

使用ng-click设置项目并传递项目并检查插件; product_template.html

<div >

    <md-button class="md-raised" ng-click="showAddons($event,product)">Add to Cart</md-button>

    </div>

controller

app.controller('productCtrl',['$scope','getProducts','orderItems','Restangular','$mdDialog',function($scope,getProducts,orderItems,Restangular,$mdDialog){
    //$scope.products;
    $scope.products = getProducts(Restangular);

    // Dialog
    $scope.showAddons=function(ev,product){
    $mdDialog.show({
        locals:{current_Product: product,},
        //inline controller
        controller:['$scope','current_Product','orderItems',function($scope,current_Product,orderItems){
        $scope.product = current_Product;
        $scope.addons = {
        checked:[],}
        ...
        }],
        templateUrl: 'dialog.html',
        targetEvent: ev, 
    })
    }

}])

dialog.html

<md-list-item ng-repeat="addon in product.productAddons">
...
<md-checkbox class="md-secondary" checklist-model="addons.checked" checklist-value="addon"></md-checkbox>
</md-list-item>
  <md-button class="md-raised" style="background-color:#f44336; color:#fff" ng-click="setOrderItems(product,addons.checked)">Done</md-button>

setOrderItems多次传递类似对象时,会出现问题。第一次,orderItems.push按预期工作,然后当类似的产品传递给&#39; setOrderItems&#39;时,它被推送到&#39; orderItems&#39;但是&#39; orderItems&#39;中的所有项目更新为此当前设置的项目。

也就是说,如果之前orderItems[{name:"chicken burrito",fillings:[{name:"cabbage"},{name:"cheese"}],...}],则在设置类似项目但使用差异填充后,orderItems会更新为[{name:"chicken burrito",filling:[{name:"guac"}],...},{name:"chicken burrito",filling:[{name:"guac"}],...}]。如果setOrderItems传递了另一个产品说[{name:"goat burrito",...}],则按预期添加。

无法找到类似的问题。我究竟做错了什么。我希望能够添加类似的项目,但使用不同的填充物orderItems

1 个答案:

答案 0 :(得分:4)

很难确切地看到你给出的代码。但如果我正在按照你正确的做法,那么问题可能在这里:

$scope.products = getProducts(Restangular);

您正在获取一组产品,我假设chicken burrito有一个对象,goat burrito有一个对象。问题我认为,就是你为每个鸡肉卷饼使用相同的对象。因此,当您将其推送到数组上时,您正在推送products中对象的引用,然后编辑该对象并再次按下它。但是你再次推动对同一个对象的引用。如果您在第二次推送之前实际查看了数组,我怀疑您会看到已经在数组上的对象已经被更改以匹配您要推送的对象,因为它是同一个对象。 / p>

要解决此问题,您需要复制该对象。为此,请看一下这个问题:

Deep copying objects in angular?

angular.copy应该让您复制product,这样您就不会总是推送同一个对象

例如,你可以这样做:

setOrderItems: function(item,fillings){
    ...
    var itemCopy = angular.copy(item);
    orderItems.push(itemCopy);
    ...
}

现在,您始终将副本推送到阵列中,阵列将填充独立的对象。