AngularJS对象应该独立工作



我有 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中。

基本上问题是objectiveDatadoneData$scope变量保持相同的内存位置。因此,更改任何值都会使所有三个值successobjectiveDatadoneData发生变化。

所以基本上你应该确保在分配一个具有多个值的变量时,创建该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

最新更新