AngularJS 对象应该独立工作
AngularJS objects should work independently
我有 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 = "";
}
});
Service: -- 从服务器获取数据
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
还有。
问题
$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);
- Object.assign:
$scope.doneData = Object.assign([], success);
AngularJS 内置函数
- angular.copy:
$scope.doneData = angular.copy(success);
- angular.extend:
$scope.doneData = angular.extend([], success);
- angular.merge (Deprecated since 1.6.5, see known issues):
$scope.doneData = angular.merge([], success);
其他技巧
$scope.doneData = JSON.parse(JSON.stringify(success));
所以而不是
$scope.objectiveData = success;
$scope.doneData = success;
Do(或任何其他先前的备选方案)
$scope.objectiveData = success.slice(); // get a copy of success
$scope.doneData = success.slice(); // get a copy of success
基本上问题是 objectiveData
& doneData
$scope 变量持有相同的内存位置。因此,更改任何值都会更改所有三个值 success
、objectiveData
和 doneData
.
所以基本上你应该确保在为一个变量分配多个值时,创建该 success
变量的克隆并保留然后将该变量分配给所需的变量。
在 angularjs 中存在 angular.copy
方法,这将帮助您创建具有新内存位置的对象的克隆。这将确保新变量将指向不同的内存位置。
控制器:
$scope.objectiveData = angular.copy(success);
$scope.doneData = angular.copy(success);
奖励: 显然你的服务实现有误,你明确地创建了一个承诺,这就是你必须在里面调用 $digest
的原因您的 .then
成功回调。这意味着您正在创建一个案例,您必须手动 运行 摘要循环,因为代码将 运行 宁在 angularjs 上下文之外。相反,您应该 return 现有的 $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);
});
}
});
我有 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 = "";
}
});
Service: -- 从服务器获取数据
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
还有。
问题
$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);
- Object.assign:
$scope.doneData = Object.assign([], success);
AngularJS 内置函数
- angular.copy:
$scope.doneData = angular.copy(success);
- angular.extend:
$scope.doneData = angular.extend([], success);
- angular.merge (Deprecated since 1.6.5, see known issues):
$scope.doneData = angular.merge([], success);
其他技巧
$scope.doneData = JSON.parse(JSON.stringify(success));
所以而不是
$scope.objectiveData = success;
$scope.doneData = success;
Do(或任何其他先前的备选方案)
$scope.objectiveData = success.slice(); // get a copy of success
$scope.doneData = success.slice(); // get a copy of success
基本上问题是 objectiveData
& doneData
$scope 变量持有相同的内存位置。因此,更改任何值都会更改所有三个值 success
、objectiveData
和 doneData
.
所以基本上你应该确保在为一个变量分配多个值时,创建该 success
变量的克隆并保留然后将该变量分配给所需的变量。
在 angularjs 中存在 angular.copy
方法,这将帮助您创建具有新内存位置的对象的克隆。这将确保新变量将指向不同的内存位置。
控制器:
$scope.objectiveData = angular.copy(success);
$scope.doneData = angular.copy(success);
奖励: 显然你的服务实现有误,你明确地创建了一个承诺,这就是你必须在里面调用 $digest
的原因您的 .then
成功回调。这意味着您正在创建一个案例,您必须手动 运行 摘要循环,因为代码将 运行 宁在 angularjs 上下文之外。相反,您应该 return 现有的 $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);
});
}
});