我有 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
中。
基本上问题是objectiveData
和doneData
$scope变量保持相同的内存位置。因此,更改任何值都会使所有三个值success
、objectiveData
和doneData
发生变化。
所以基本上你应该确保在分配一个具有多个值的变量时,创建该success
变量的克隆,然后保留然后将该变量分配给所需的变量。
在angularjs中,存在angular.copy
方法,它将帮助您创建具有新内存位置的对象克隆。这将确保新变量将指向不同的内存位置。
控制器:
$scope.objectiveData = angular.copy(success);
$scope.doneData = angular.copy(success);
奖励:很明显,您的服务实现似乎有错误,您正在明确地创建一个承诺,这就是为什么您必须在.then
成功回调中调用$digest
的原因。这意味着您正在创建一个必须手动运行摘要循环的情况,因为代码将在 angularjs 上下文之外运行。相反,您应该返回如下所示的现有$http
承诺,并从代码中删除根本不需要的$scope.$digest()
。
服务
myApp.service("lastday_data", function($http) {
this.getData = function() {
return $http({
method: 'GET',
url: 'http://localhost/task/index.php/v1/example/users'
}).then(function(response) {
if (response.status)
return response.data;
else
return $q.reject('Problem retrieving data');
}, function(error) {
return $q.reject(error);
});
}
});
问题
$scope.objectiveData
和$scope.doneData
都引用同一个变量success
,所以如果你改变一个,另一个也会改变。
溶液
通过获取success
的独立副本,使$scope.objectiveData
和$scope.doneData
引用自变量。你可以为此使用
普通的JavaScript
- Array.prototype.slice:
$scope.doneData = success.slice();
- Array.prototype.concat:
$scope.doneData = [].concat(success);
- Array.from:
$scope.doneData = Array.from(success);
- 对象分配:
$scope.doneData = Object.assign([], success);
AngularJS内置函数
- 角度复制:
$scope.doneData = angular.copy(success);
- 角度扩展:
$scope.doneData = angular.extend([], success);
- angular.merge(自 1.6.5 起已弃用,请参阅已知问题(:
$scope.doneData = angular.merge([], success);
其他技巧
- JSON.parse/JSON.stringify[1]:
$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