Angularjs $ Rootscope阵列的用户输入对象被上次输入覆盖



以下是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 Controller相对应的HTML DIV代码如下:

<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时。阶段的最后阶段是覆盖所有以前的阶段。例如,

首先我推了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}
]

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

有任何想法

您正在使用$scope.stage的JavaScript引用,即使您将新"对象"推入阶段,它也是一个更新的引用,这意味着上一个对象也会更新其值。尝试包装

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

to

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

尝试no $ rootscope示例:

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

请参阅此处的演示:jsfiddle

最新更新