I've been saving all the data received from services direct to local variable, controller, or scope. What I suppose would be considered a shallow copy, is that correct?
我将从服务接收的所有数据直接保存到本地变量、控制器或范围。我认为这是一个浅显的副本,对吗?
Example:
DataService.callFunction()
.then(function(response) {
$scope.example = response.data;
});
Recently I was told to use angular.copy in order to create a deep copy.
最近有人告诉我要用角。复制以创建一个深度拷贝。
$scope.example = angular.copy(response.data);
However, the deep copy information seems to be working in the same way when used by my Angular application. Are there specific benefits to using a deep copy (angular.copy) and can you please explain them to me?
然而,当我的角度应用时,深层拷贝信息似乎以同样的方式工作。使用深度拷贝(angular.copy)有什么特别的好处吗?你能给我解释一下吗?
7 个解决方案
#1
134
Use angular.copy when assigning value of object or array to another variable and that object
value should not be changed.
使用角。当将对象或数组的值赋值给另一个变量时,该对象的值不应被更改。
Without deep copy or using angular.copy, changing value of property or adding any new property update all object referencing that same object.
没有深度复制或使用角度。复制、更改属性值或添加任何新属性更新所有引用相同对象的对象。
var app = angular.module('copyExample', []);
app.controller('ExampleController', ['$scope',
function($scope) {
$scope.printToConsole = function() {
$scope.main = {
first: 'first',
second: 'second'
};
$scope.child = angular.copy($scope.main);
console.log('Main object :');
console.log($scope.main);
console.log('Child object with angular.copy :');
console.log($scope.child);
$scope.child.first = 'last';
console.log('New Child object :')
console.log($scope.child);
console.log('Main object after child change and using angular.copy :');
console.log($scope.main);
console.log('Assing main object without copy and updating child');
$scope.child = $scope.main;
$scope.child.first = 'last';
console.log('Main object after update:');
console.log($scope.main);
console.log('Child object after update:');
console.log($scope.child);
}
}
]);
// Basic object assigning example
var main = {
first: 'first',
second: 'second'
};
var one = main; // same as main
var two = main; // same as main
console.log('main :' + JSON.stringify(main)); // All object are same
console.log('one :' + JSON.stringify(one)); // All object are same
console.log('two :' + JSON.stringify(two)); // All object are same
two = {
three: 'three'
}; // two changed but one and main remains same
console.log('main :' + JSON.stringify(main)); // one and main are same
console.log('one :' + JSON.stringify(one)); // one and main are same
console.log('two :' + JSON.stringify(two)); // two is changed
two = main; // same as main
two.first = 'last'; // change value of object's property so changed value of all object property
console.log('main :' + JSON.stringify(main)); // All object are same with new value
console.log('one :' + JSON.stringify(one)); // All object are same with new value
console.log('two :' + JSON.stringify(two)); // All object are same with new value
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="copyExample" ng-controller="ExampleController">
<button ng-click='printToConsole()'>Explain</button>
</div>
#2
32
In that case, you don't need to use angular.copy()
在这种情况下,不需要使用angular.copy()
Explanation :
解释:
-
=
represents a reference whereasangular.copy()
creates a new object as a deep copy.=表示引用,而angular.copy()创建一个新对象作为深度副本。
-
Using
=
would mean that changing a property ofresponse.data
would change the corresponding property of$scope.example
or vice versa.使用=意味着改变响应的属性。数据将改变$scope的相应属性。例子,反之亦然。
-
Using
angular.copy()
the two objects would remain seperate and changes would not reflect on each other.使用angular.copy()这两个对象将保持分离,更改不会相互反映。
#3
7
I would say angular.copy(source);
in your situation is unnecessary if later on you do not use is it without a destination angular.copy(source, [destination]);
.
我想说angular.copy(源);在你的情况下是不必要的,如果以后你不使用是它没有目的角。复制(源,(目的地));。
If a destination is provided, all of its elements (for arrays) or properties (for objects) are deleted and then all elements/properties from the source are copied to it.
如果提供了目标,则删除其所有元素(用于数组)或属性(用于对象),然后将源中的所有元素/属性复制到目标中。
https://docs.angularjs.org/api/ng/function/angular.copy
https://docs.angularjs.org/api/ng/function/angular.copy
#4
1
I am just sharing my experience here, I used angular.copy() for comparing two objects properties. I was working on a number of inputs without form element, I was wondering how to compare two objects properties and based on result I have to enable and disable the save button. So I used as below.
我只是在这里分享我的经验,我使用了angular.copy()来比较两个对象属性。我正在处理一些没有表单元素的输入,我想知道如何比较两个对象属性,基于结果,我必须启用和禁用save按钮。我用了如下图。
I assigned a original server object user values to my dummy object say userCopy and used watch to check changes to user object.
我为我的虚拟对象(比如userCopy)分配了一个原始的服务器对象用户值,并使用watch检查对user对象的更改。
my server API which gets me data from server
从服务器获取数据的服务器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();
});
//initially my save button is disabled because objects are same, once something //changes I am activing save btn
//最初我的save按钮是禁用的,因为对象是相同的,一旦发生了//更改,我将保存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);
I am not sure but comparing two objects was really headche for me always but with angular.copy() its went smothly.
我不确定,但是比较两个物体对我来说总是很困难,但是对天使来说。
#5
1
When using angular.copy, instead of updating the reference, a new object is created and assigned to the destination(if a destination is provided). But there's more. There's this cool thing that happens after a deep copy.
当使用角。复制,而不是更新引用,创建一个新的对象并分配给目标(如果提供了目标)。但还有更多。有一件很酷的事情发生在深度复制之后。
Say you have a factory service which has methods which updates factory variables.
假设您有一个工厂服务,它有更新工厂变量的方法。
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;
}]);
and a controller which uses this service,
一个使用这个服务的控制器,
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);
}]);
When the above program is run the output will be as follows,
当运行上述程序时,输出如下,
****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]
Thus the cool thing about using angular copy is that, the references of the destination are reflected with the change of values, without having to re-assign the values manually, again.
因此,使用角复制的最酷之处在于,目标的引用会随着值的变化而反映,而不必再次手动地重新分配值。
#6
0
I know its already answered, still i am just trying to make it simple. So angular.copy(data) you can use in case where you want to modify/change your received object by keeping its original values unmodified/unchanged.
我知道它已经回答了,但我只是想让它变得简单。因此,当您希望修改/更改接收对象时,可以使用angular.copy(data)来保持其原始值不变。
For example: suppose i have made api call and got my originalObj, now i want to change the values of api originalObj for some case but i want the original values too so what i can do is, i can make a copy of my api originalObj in duplicateObj and modify duplicateObj this way my originalObj values will not change. In simple words duplicateObj modification will not reflect in originalObj unlike how js obj behave.
例如:假设我originalObj api调用和有,现在我想改变的值api originalObj对于某些情况下但我希望原始值太所以我能做的就是,我可以复制我的api originalObj duplicateObj和修改duplicateObj这样我originalObj值不会改变。简单来说,复制obj修改不会像js obj的行为那样反映在originalObj中。
$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);
Result is like....
结果就像....
----------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"}
#7
-2
Javascript passes variables by reference
, this means that:
Javascript通过引用传递变量,这意味着:
var i = [];
var j = i;
i.push( 1 );
Now because of by reference
part i
is [1], and j
is [1] as well, even though only i
was changed. This is because when we say j = i
javascript doesn't copy the i
variable and assign it to j
but references i
variable through j
.
由于引用部分i是[1],j也是[1],尽管只有我被修改过。这是因为当我们说j = i时javascript不会复制i变量并将其赋给j,而是通过j引用i变量。
Angular copy lets us lose this reference, which means:
角拷贝让我们失去了这个参考,这意味着:
var i = [];
var j = angular.copy( i );
i.push( 1 );
Now i
here equals to [1], while j
still equals to [].
现在i等于[1],而j仍然等于[]。
There are situations when such kind of copy
functionality is very handy.
在某些情况下,这种复制功能非常方便。
#1
134
Use angular.copy when assigning value of object or array to another variable and that object
value should not be changed.
使用角。当将对象或数组的值赋值给另一个变量时,该对象的值不应被更改。
Without deep copy or using angular.copy, changing value of property or adding any new property update all object referencing that same object.
没有深度复制或使用角度。复制、更改属性值或添加任何新属性更新所有引用相同对象的对象。
var app = angular.module('copyExample', []);
app.controller('ExampleController', ['$scope',
function($scope) {
$scope.printToConsole = function() {
$scope.main = {
first: 'first',
second: 'second'
};
$scope.child = angular.copy($scope.main);
console.log('Main object :');
console.log($scope.main);
console.log('Child object with angular.copy :');
console.log($scope.child);
$scope.child.first = 'last';
console.log('New Child object :')
console.log($scope.child);
console.log('Main object after child change and using angular.copy :');
console.log($scope.main);
console.log('Assing main object without copy and updating child');
$scope.child = $scope.main;
$scope.child.first = 'last';
console.log('Main object after update:');
console.log($scope.main);
console.log('Child object after update:');
console.log($scope.child);
}
}
]);
// Basic object assigning example
var main = {
first: 'first',
second: 'second'
};
var one = main; // same as main
var two = main; // same as main
console.log('main :' + JSON.stringify(main)); // All object are same
console.log('one :' + JSON.stringify(one)); // All object are same
console.log('two :' + JSON.stringify(two)); // All object are same
two = {
three: 'three'
}; // two changed but one and main remains same
console.log('main :' + JSON.stringify(main)); // one and main are same
console.log('one :' + JSON.stringify(one)); // one and main are same
console.log('two :' + JSON.stringify(two)); // two is changed
two = main; // same as main
two.first = 'last'; // change value of object's property so changed value of all object property
console.log('main :' + JSON.stringify(main)); // All object are same with new value
console.log('one :' + JSON.stringify(one)); // All object are same with new value
console.log('two :' + JSON.stringify(two)); // All object are same with new value
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="copyExample" ng-controller="ExampleController">
<button ng-click='printToConsole()'>Explain</button>
</div>
#2
32
In that case, you don't need to use angular.copy()
在这种情况下,不需要使用angular.copy()
Explanation :
解释:
-
=
represents a reference whereasangular.copy()
creates a new object as a deep copy.=表示引用,而angular.copy()创建一个新对象作为深度副本。
-
Using
=
would mean that changing a property ofresponse.data
would change the corresponding property of$scope.example
or vice versa.使用=意味着改变响应的属性。数据将改变$scope的相应属性。例子,反之亦然。
-
Using
angular.copy()
the two objects would remain seperate and changes would not reflect on each other.使用angular.copy()这两个对象将保持分离,更改不会相互反映。
#3
7
I would say angular.copy(source);
in your situation is unnecessary if later on you do not use is it without a destination angular.copy(source, [destination]);
.
我想说angular.copy(源);在你的情况下是不必要的,如果以后你不使用是它没有目的角。复制(源,(目的地));。
If a destination is provided, all of its elements (for arrays) or properties (for objects) are deleted and then all elements/properties from the source are copied to it.
如果提供了目标,则删除其所有元素(用于数组)或属性(用于对象),然后将源中的所有元素/属性复制到目标中。
https://docs.angularjs.org/api/ng/function/angular.copy
https://docs.angularjs.org/api/ng/function/angular.copy
#4
1
I am just sharing my experience here, I used angular.copy() for comparing two objects properties. I was working on a number of inputs without form element, I was wondering how to compare two objects properties and based on result I have to enable and disable the save button. So I used as below.
我只是在这里分享我的经验,我使用了angular.copy()来比较两个对象属性。我正在处理一些没有表单元素的输入,我想知道如何比较两个对象属性,基于结果,我必须启用和禁用save按钮。我用了如下图。
I assigned a original server object user values to my dummy object say userCopy and used watch to check changes to user object.
我为我的虚拟对象(比如userCopy)分配了一个原始的服务器对象用户值,并使用watch检查对user对象的更改。
my server API which gets me data from server
从服务器获取数据的服务器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();
});
//initially my save button is disabled because objects are same, once something //changes I am activing save btn
//最初我的save按钮是禁用的,因为对象是相同的,一旦发生了//更改,我将保存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);
I am not sure but comparing two objects was really headche for me always but with angular.copy() its went smothly.
我不确定,但是比较两个物体对我来说总是很困难,但是对天使来说。
#5
1
When using angular.copy, instead of updating the reference, a new object is created and assigned to the destination(if a destination is provided). But there's more. There's this cool thing that happens after a deep copy.
当使用角。复制,而不是更新引用,创建一个新的对象并分配给目标(如果提供了目标)。但还有更多。有一件很酷的事情发生在深度复制之后。
Say you have a factory service which has methods which updates factory variables.
假设您有一个工厂服务,它有更新工厂变量的方法。
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;
}]);
and a controller which uses this service,
一个使用这个服务的控制器,
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);
}]);
When the above program is run the output will be as follows,
当运行上述程序时,输出如下,
****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]
Thus the cool thing about using angular copy is that, the references of the destination are reflected with the change of values, without having to re-assign the values manually, again.
因此,使用角复制的最酷之处在于,目标的引用会随着值的变化而反映,而不必再次手动地重新分配值。
#6
0
I know its already answered, still i am just trying to make it simple. So angular.copy(data) you can use in case where you want to modify/change your received object by keeping its original values unmodified/unchanged.
我知道它已经回答了,但我只是想让它变得简单。因此,当您希望修改/更改接收对象时,可以使用angular.copy(data)来保持其原始值不变。
For example: suppose i have made api call and got my originalObj, now i want to change the values of api originalObj for some case but i want the original values too so what i can do is, i can make a copy of my api originalObj in duplicateObj and modify duplicateObj this way my originalObj values will not change. In simple words duplicateObj modification will not reflect in originalObj unlike how js obj behave.
例如:假设我originalObj api调用和有,现在我想改变的值api originalObj对于某些情况下但我希望原始值太所以我能做的就是,我可以复制我的api originalObj duplicateObj和修改duplicateObj这样我originalObj值不会改变。简单来说,复制obj修改不会像js obj的行为那样反映在originalObj中。
$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);
Result is like....
结果就像....
----------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"}
#7
-2
Javascript passes variables by reference
, this means that:
Javascript通过引用传递变量,这意味着:
var i = [];
var j = i;
i.push( 1 );
Now because of by reference
part i
is [1], and j
is [1] as well, even though only i
was changed. This is because when we say j = i
javascript doesn't copy the i
variable and assign it to j
but references i
variable through j
.
由于引用部分i是[1],j也是[1],尽管只有我被修改过。这是因为当我们说j = i时javascript不会复制i变量并将其赋给j,而是通过j引用i变量。
Angular copy lets us lose this reference, which means:
角拷贝让我们失去了这个参考,这意味着:
var i = [];
var j = angular.copy( i );
i.push( 1 );
Now i
here equals to [1], while j
still equals to [].
现在i等于[1],而j仍然等于[]。
There are situations when such kind of copy
functionality is very handy.
在某些情况下,这种复制功能非常方便。