我一直在将从服务收到的所有数据直接保存到本地变量,控制器或范围。我认为它会被认为是浅层副本,这是正确的吗?
Example:
DataService.callFunction()
.then(function(response) {
$scope.example = response.data;
});
最近我被告知要使用angular.copy来创建深层副本。
$scope.example = angular.copy(response.data);
然而,当我的Angular应用程序使用时,深层复制信息似乎以相同的方式工作。 使用深层副本(angular.copy)是否有特定的好处,请您向我解释一下?
答案 0 :(得分:41)
在这种情况下,您无需使用angular.copy()
解释:
=
表示引用,而angular.copy()
创建新对象作为深层副本。
使用=
意味着更改response.data
的属性会更改$scope.example
的相应属性,反之亦然。
使用angular.copy()
两个对象将保持独立,并且更改不会相互反映。
答案 1 :(得分:7)
我会说angular.copy(source);
在您的情况下是不必要的,如果您以后不使用它是没有目的地angular.copy(source, [destination]);
。
如果提供了目标,则其所有元素(对于数组) 或属性(对象)被删除,然后全部删除 来自源的元素/属性将被复制到它。
答案 2 :(得分:1)
我只是在这里分享我的经验,我使用angular.copy()来比较两个对象属性。我正在处理一些没有表单元素的输入,我想知道如何比较两个对象属性,并根据结果我必须启用和禁用保存按钮。所以我使用如下。
我将原始服务器对象用户值分配给我的虚拟对象说userCopy并使用watch来检查用户对象的更改。
我的服务器API从服务器获取数据
var req = {
method: 'GET',
url: 'user/profile/'+id,
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
}
$http(req).success(function(data) {
$scope.user = data;
$scope.userCopy = angular.copy($scope.user);
$scope.btnSts=true;
}).error(function(data) {
$ionicLoading.hide();
});
//最初我的保存按钮被禁用,因为对象是相同的,一旦//更改我正在活动保存btn
$scope.btnSts=true;
$scope.$watch('user', function(newVal, oldVal){
console.log($scope.userCopy.name);
console.log();
if ($scope.userCopy.name !== $scope.user.name || $scope.userCopy.email !== $scope.user.email ) {
console.log('changed');
$scope.btnSts=false;
}else{
console.log('unchanged');
$scope.btnSts=true;
}
}, true);
我不确定但是比较两个对象总是对我来说总是如此,但是使用angular.copy()它会变得很光滑。
答案 3 :(得分:1)
使用angular.copy时,不是更新引用,而是创建新对象并将其分配给目标(如果提供了目标)。但还有更多。在深层复制之后会发生这种很酷的事情。
假设您有一个工厂服务,其中包含更新工厂变量的方法。
angular.module('test').factory('TestService', [function () {
var o = {
shallow: [0,1], // initial value(for demonstration)
deep: [0,2] // initial value(for demonstration)
};
o.shallowCopy = function () {
o.shallow = [1,2,3]
}
o.deepCopy = function () {
angular.copy([4,5,6], o.deep);
}
return o;
}]);
和使用此服务的控制器
angular.module('test').controller('Ctrl', ['TestService', function (TestService) {
var shallow = TestService.shallow;
var deep = TestService.deep;
console.log('****Printing initial values');
console.log(shallow);
console.log(deep);
TestService.shallowCopy();
TestService.deepCopy();
console.log('****Printing values after service method execution');
console.log(shallow);
console.log(deep);
console.log('****Printing service variables directly');
console.log(TestService.shallow);
console.log(TestService.deep);
}]);
运行上述程序时,输出如下,
****Printing initial values
[0,1]
[0,2]
****Printing values after service method execution
[0,1]
[4,5,6]
****Printing service variables directly
[1,2,3]
[4,5,6]
因此,使用角度复制的一个很酷的事情是,目标的引用会反映为值的更改,而不必再次手动重新分配值。
答案 4 :(得分:1)
我知道它已经回答了,我仍然只是想让它变得简单。 因此,如果您希望通过保持原始值未修改/未更改来修改/更改接收到的对象,则可以使用angular.copy(数据)。
例如:假设我已经进行了api调用并获得了我的originalObj,现在我想在某些情况下更改api originalObj的值,但我想要原始值,所以我能做的就是,我可以在duplicateObj中复制我的api originalObj并修改duplicateObj,这样我的originalObj值就不会改变。简单来说,duplicateObj修改将不会反映在originalObj中,这与js obj的行为方式不同。
$scope.originalObj={
fname:'sudarshan',
country:'India'
}
$scope.duplicateObj=angular.copy($scope.originalObj);
console.log('----------originalObj--------------');
console.log($scope.originalObj);
console.log('-----------duplicateObj---------------');
console.log($scope.duplicateObj);
$scope.duplicateObj.fname='SUD';
$scope.duplicateObj.country='USA';
console.log('---------After update-------')
console.log('----------originalObj--------------');
console.log($scope.originalObj);
console.log('-----------duplicateObj---------------');
console.log($scope.duplicateObj);
结果就像....
----------originalObj--------------
manageProfileController.js:1183 {fname: "sudarshan", country: "India"}
manageProfileController.js:1184 -----------duplicateObj---------------
manageProfileController.js:1185 {fname: "sudarshan", country: "India"}
manageProfileController.js:1189 ---------After update-------
manageProfileController.js:1190 ----------originalObj--------------
manageProfileController.js:1191 {fname: "sudarshan", country: "India"}
manageProfileController.js:1192 -----------duplicateObj---------------
manageProfileController.js:1193 {fname: "SUD", country: "USA"}
答案 5 :(得分:-2)
Javascript传递变量by reference
,这意味着:
var i = [];
var j = i;
i.push( 1 );
现在因为by reference
部分i
是[1]而j
也是[1],即使只有i
被更改了。这是因为当我们说j = i
时,javascript不会复制i
变量并将其分配给j
,而是通过i
引用j
变量。
Angular copy让我们失去了这个引用,这意味着:
var i = [];
var j = angular.copy( i );
i.push( 1 );
现在i
等于[1],而j
仍然等于[]。
在某些情况下,这种copy
功能非常方便。