为什么以及何时使用angular.copy? (深度复制)
我一直保存从服务接收的所有数据直接到本地variables,控制器或范围。 我认为会被认为是浅拷贝,这是正确的吗?
Example: DataService.callFunction() .then(function(response) { $scope.example = response.data; });
最近我被告知要使用angular.copy来创build一个深层副本。
$scope.example = angular.copy(response.data);
但是,当我的Angular应用程序使用深度复制信息时,似乎也是以相同的方式工作的。 使用深层拷贝(angular.copy)有什么特别的好处,你可以向我解释一下吗?
在将对象或数组的值分配给另一个variables时使用angular.copy ,并且不应更改该object
值。
没有深拷贝或使用angular.copy ,更改属性的值或添加任何新的属性更新引用同一对象的所有对象。
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>
在这种情况下,你不需要使用angular.copy()
说明 :
-
=
表示一个引用,而angular.copy()
创build一个新的对象作为深层副本。 -
使用
=
意味着改变response.data
的属性会改变$scope.example
的相应属性,反之亦然。 -
使用
angular.copy()
这两个对象将保持独立,变化不会相互反映。
我会说angular.copy(source);
在你的情况是不必要的,如果以后你不使用它没有一个目的地angular.copy(source, [destination]);
。
如果提供了一个目的地,那么它的所有元素(对于数组)或属性(对于对象)都将被删除,然后将所有来自源的元素/属性复制到它。
我只是在这里分享我的经验,我用angular.copy()比较两个对象的属性。 我正在处理一些没有表单元素的input,我想知道如何比较两个对象的属性,并根据结果我必须启用和禁用保存button。 所以我使用如下。
我分配了一个原始的服务器对象用户值到我的虚拟对象说userCopy,并用手表来检查用户对象的变化。
我的服务器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(); });
/ /最初我的保存button被禁用,因为对象是相同的,一旦//更改我正在保存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()却变得非常糟糕。
使用angular.copy时,不是更新引用,而是创build一个新对象并将其分配给目标(如果提供了目标)。 但还有更多。 有一个很酷的事情发生在深拷贝之后。
假设你有一个工厂服务,它具有更新工厂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; }]);
以及使用该服务的控制器,
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]
因此,使用angular度复制的好处是,目标的引用会随着值的变化而反映出来,而不必手动重新赋值。
JavaScript通过by reference
传递variables,这意味着:
var i = []; var j = i; i.push( 1 );
现在因为by reference
部分i
是[1],并且j
也是[1],即使只有i
被改变了。 这是因为当我们说j = i
JavaScript不复制i
variables,并将其分配给j
但通过j
引用i
variables。
angular度复制让我们失去了这个参考,这意味着:
var i = []; var j = angular.copy( i ); i.push( 1 );
现在i
在这里等于[1],而j
仍然等于[]。
有些情况下,这种copy
function非常方便。