AngularJS $ rootScope用户输入的对象数组被最后一个条目覆盖

时间:2017-02-28 13:24:39

标签: javascript jquery html angularjs

以下是带有运行块的AngularJS应用程序,用于rootScope初始化某些数组,服务和控制器:

var myApp = angular.module('myApp',['ngAnimate','ui.bootstrap']);
angular.module('myApp').run(function($rootScope) {
$rootScope.stages = [];
$rootScope.stage = {
        level : 1,
        field1 : 'myValue1',
        field2 : 'myValue2',
        field3 : {
            field4 : 'myValue4',
            field5 : {
                field6 : 'myValue6'
            }
        }
};
});
angular.module('myApp').service('stagesService', function($rootScope) {
    return {
        stages: function () {
            return $rootScope.stages;
        },
        addStage: function () {
            console.log("Inside stagesService.addStage");
            console.log($rootScope.stage);
            $rootScope.stages.push($rootScope.stage);
            /*angular.forEach($rootScope.stages, function() {
                this.push($rootScope.stage);
            });*/
            return true;
        }
    };
});
angular.module('myApp').controller('StageFormModalCtrl', [ '$rootScope', '$scope', 'stagesService', '$filter', function($rootScope, $scope, stagesService, $filter) {
$scope.addStage = function() {
            stagesService.addStage();
            console.log("Added Stage : "+stagesService.getStage(1).level + ","+stagesService.getStage(1).query + ","+ stagesService.getStage(1).expectedfilename);          
            $scope.stages(); //<-- updating rootscope stages Array each time a new stage is added
        }
}
$scope.stages = function() {
var currstages = stagesService.stages();
console.log(currstages);
}
}]);

与提交舞台输入的模态表格相对应的HTML div代码与StageFormModalCtrl控制器对应如下:

<div class="modal fade" id="stageModal" role="dialog" tabindex="-1"
                aria-labelledby="stageModalLabel" aria-hidden="true">
                <div class="modal-dialog">

                <div class="modal-content">
                <div class="modal-header">
                    <button type="button" class="close" data-dismiss="modal">
                        <span aria-hidden="true">&times;</span>
                        <span class="sr-only">Close</span>
                    </button>
                    <h4 class="modal-title" id="stageModallabel">Enter stage</h4>               
                </div>
                <div class="modal-body">
                    <form name="stageInputForm" class="form-horizontal" role="form" 
                    ng-controller="StageFormModalCtrl">
                    <div class="form-group">
                    <label class="col-sm-2 control-label" for="level">Enter Level</label>
                    <div class="col-sm-10"> 

                        <input type="number" string-to-number min="1" step="1" name="level" id="level" class="form-control"
                        ng-model="stage.level"/>
                    </div>
                    </div>
                    <div class="form-group">
                    <label class="col-sm-2 control-label" for="field1">Enter field1</label>
                    <div class="col-sm-10"> 

                        <textarea row="4" cols="50" name="field1" id="field1" class="form-control" 
                        ng-model="stage.field1"></textarea>
                    </div>
                    </div>
                    <div class="form-group">
                    <label class="col-sm-2 control-label" for="field2">Enter field2</label>
                    <div class="col-sm-10">

                        <input type="text" name="field2" id="field2" class="form-control"
                        ng-model="stage.field2"/>
                    </div>
                    </div>
                    <div class="modal-footer">
                    <button type="button" class="btn btn-default"
                        data-dismiss="modal">Close</button>
                    <button type="button" class="btn btn-primary" ng-click="addStage()">Add</button>
                </div>
                    </form>
                </div>

            </div>
            </div>
            </div>

舞台表单输入是数据绑定到$ rootScope.stage字段,单击“添加”按钮后,应根据表单中提供的任何输入添加各个阶段。

但是在将多个阶段推入$ rootScope.stages的同时,最后一个阶段将覆盖所有之前的阶段。例如,

首先我推了level=1, field1="X", field2="Y"

$rootScope.stages = [{level : 1, field1 : X, field2 : Y}]

然后我推了level=2, field1="W", field2="Z"

$rootScope.stages = [{level : 2, field1 : W, field2 : Z},
                     {level : 2, field1 : W, field2 : Z}
]

而不是

$rootScope.stages = [{level : 1, field1 : X, field2 : Y},
                     {level : 2, field1 : W, field2 : Z}
]

为什么会发生这种奇怪的覆盖?

2 个答案:

答案 0 :(得分:2)

您正在使用$scope.stage的javascript引用,即使您将新的“对象”分成几个阶段,它也会更新引用,这意味着前一个对象也会更新其值。 尝试包装

$rootScope.stages.push($rootScope.stage)

$rootScope.stages.push(angular.copy($rootScope.stage));

答案 1 :(得分:1)

尝试no $ rootScope示例:

angular.module('myApp').service('stagesService', function() {
    var stages = [];
    return {
        getStages: function () {
            return stages;
        },
        addStage: function (stage) {
            stages.push(stage);
            return true;
        }
    };
});

在此处查看演示:jsfiddle