我有2个数组对象,都用$ http响应初始化,但是当我尝试在一个数组中添加(推入)时,它将同时添加到两个数组中。
我尝试了以下代码:
控制器:
myApp.controller("abc", function($scope, lastday_data){
$scope.objectiveData = [];
$scope.doneData = [];
// call service & get data from server
lastday_data.getData().then(function(success){
$scope.objectiveData = success;
$scope.doneData = success;
$scope.$digest(); // *---> $digest() used*
},function(error){
$scope.objectiveData = null;
$scope.doneData = null;
});
// add task done
$scope.addTaskDone = function() {
var p = {"id": 101, "name": "testadd", "check": true};
$scope.doneData.push(p);
$scope.textDone = "";
}
});
服务:-从服务器获取数据
myApp.service("lastday_data", function($http){
this.getData = function() {
return new Promise(function(resolve, reject){
$http({
method: 'GET',
url: 'http://localhost/task/index.php/v1/example/users'
}).then(function (response) {
if(response.status)
resolve(response.data);
else
reject();
},function (error) {
reject();
});
});
}
});
问题::当我尝试调用控制器的addTaskDone()
方法时,此方法在doneData
数组中添加了一个对象,但也在objectiveData
中也添加了该对象。
答案 0 :(得分:3)
基本上,问题是objectiveData
和doneData
$ scope变量持有相同的内存位置。因此,更改任何一个值都将同时更改三个值success
,objectiveData
和doneData
。
因此,基本上,您应该确保在分配一个具有多个值的变量时,创建该success
变量的克隆,然后保留该变量,然后将其分配给所需的变量。
在angularjs中,存在angular.copy
方法,该方法将帮助您创建具有新内存位置的对象的克隆。这将确保新变量将指向不同的内存位置。
控制器:
$scope.objectiveData = angular.copy(success);
$scope.doneData = angular.copy(success);
奖金:很明显,您在服务的实现上有错误,您在其中明确创建了一个诺言,这就是您必须在{{1}中调用$digest
的原因}成功回调。这意味着您正在创建一种情况,您必须手动运行摘要循环,因为代码将在angularjs上下文之外运行。相反,您应该像下面那样返回现有的.then
承诺,并从根本不需要的代码中删除$http
。
服务
$scope.$digest()
答案 1 :(得分:0)
$scope.objectiveData
和$scope.doneData
都引用相同的变量success
,因此,如果您更改一个,则另一个也将更改。
通过获取$scope.objectiveData
的独立副本,使$scope.doneData
和success
引用独立变量。您可以为此使用
普通JavaScript
$scope.doneData = success.slice();
$scope.doneData = [].concat(success);
$scope.doneData = Array.from(success);
$scope.doneData = Object.assign([], success);
AngularJS内置函数
$scope.doneData = angular.copy(success);
$scope.doneData = angular.extend([], success);
$scope.doneData = angular.merge([], success);
其他技巧
$scope.doneData = JSON.parse(JSON.stringify(success));
所以而不是
$scope.objectiveData = success;
$scope.doneData = success;
执行(或之前的任何其他替代方法)
$scope.objectiveData = success.slice(); // get a copy of success
$scope.doneData = success.slice(); // get a copy of success