Programing

언제 그리고 언제 angular.copy를 사용해야합니까?

lottogame 2020. 7. 1. 08:01
반응형

언제 그리고 언제 angular.copy를 사용해야합니까? (딥 카피)


서비스에서받은 모든 데이터를 로컬 변수, 컨트롤러 또는 범위에 직접 저장했습니다. 내가 얕은 사본으로 간주 될 것이라고 생각하는 것이 맞습니까?

Example:

DataService.callFunction()
.then(function(response) {
  $scope.example = response.data;
});

최근에는 깊은 사본을 만들기 위해 angular.copy를 사용하라는 지시를 받았습니다.

$scope.example = angular.copy(response.data);

그러나 딥 카피 정보는 Angular 응용 프로그램에서 사용할 때와 같은 방식으로 작동하는 것 같습니다. 딥 카피 (angular.copy)를 사용하면 특별한 이점이 있습니까? 설명해 주시겠습니까?


객체 또는 배열의 값을 다른 변수에 할당 할 때 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()새 개체를 깊은 복사본으로 만듭니다.

  • 를 사용하면 =속성을 response.data변경하면 해당 속성이 변경 $scope.example되거나 그 반대로 변경됩니다.

  • angular.copy()두 개체를 사용 하면 별도로 유지되며 변경 사항은 서로 반영되지 않습니다.


angular.copy(source);나중에 사용하지 않으면 목적지가 없으면 상황이 불필요 하다고 말하고 싶습니다 angular.copy(source, [destination]);.

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


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.


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.

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.

 $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"}

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.

I assigned an original server object user values to my dummy object to say userCopy and used watch to check changes to the user object.

My server API which gets me data from the server:

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 activating save button

$scope.btnSts = true;
$scope.$watch('user', function(newVal, oldVal) {
    console.log($scope.userCopy.name);

    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 headache for me always but with angular.copy() it went smoothly.


Javascript passes variables by reference, this means that:

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.

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 [].

There are situations when such kind of copy functionality is very handy.

참고URL : https://stackoverflow.com/questions/33043850/why-and-when-to-use-angular-copy-deep-copy

반응형