কেন এবং কখন কৌনিক কোডপি ব্যবহার করবেন? (গভীর অনুলিপি)


136

আমি পরিষেবাগুলি থেকে প্রাপ্ত সমস্ত ডেটা সরাসরি স্থানীয় ভেরিয়েবল, নিয়ামক বা স্কোপে সংরক্ষণ করে আসছি। আমি মনে করি যা অগভীর অনুলিপি হিসাবে বিবেচিত হবে, তা কি সঠিক?

Example:

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

সম্প্রতি আমাকে একটি অনুলিপি তৈরি করতে কৌনিক কোডি ব্যবহার করতে বলা হয়েছিল।

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

তবে, আমার কৌনিক অ্যাপ্লিকেশনটি ব্যবহার করার সময় গভীর অনুলিপি তথ্য একইভাবে কাজ করছে বলে মনে হচ্ছে। একটি গভীর অনুলিপি (কৌণিক.কপি) ব্যবহারের কোনও নির্দিষ্ট সুবিধা রয়েছে এবং আপনি দয়া করে আমাকে সেগুলি ব্যাখ্যা করতে পারেন?


2
আপনার অবজেক্টের অনুলিপি (: ডি) প্রয়োজন হলে আপনাকে কৌনিক কোডপি ব্যবহার করা উচিত। আপনি যদি আজাক্স কল ($ http, $ উত্স, ...) থেকে অবজেক্টটি পান তবে অনুলিপি করার দরকার নেই। তবে আপনি যদি এই বিষয়টিকে দৃষ্টিতে পরিবর্তন করতে চান তবে মূল অবজেক্টটি কোনও ধরণের ক্যাশে রাখুন, আপনি অনুলিপি করতে পারেন।
পেট্র আভেরিয়ানভ

উত্তর:


166

অন্য ভেরিয়েবলের জন্য অবজেক্ট বা অ্যারের মান নির্ধারণের সময় অ্যাঙ্গুলারকপি ব্যবহার করুন এবং সেই 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>


1
দ্রুত প্রতিক্রিয়াটির জন্য অনেক ধন্যবাদ, সহায়তাটি পছন্দ করুন এবং আমার মনে হয় আমি বুঝতে পেরেছি। আঙ্গুলের কপি ব্যবহারের একমাত্র আসল সময়টি ছিল আক্ষরিক অনুলিপিটির জন্য। মানে আমার কেবল তখনই ব্যবহার করা উচিত যখন আমি বৈশিষ্ট্যটিতে পরিবর্তন করতে পারি সেই আসলটির সদৃশ প্রয়োজন need আমি কি দুটি পৃথক ভেরিয়েবলের তথ্য সংরক্ষণ করতে পারি এবং কৌনিক কোডপি তৈরির পরিবর্তে তাদের সম্পত্তিগুলি পৃথক করে সামঞ্জস্য করতে পারি? উদাহরণ: $scope.one = response.dataএবং সেট $scope.two = response.data। তাহলে কর $scope.two.addProperty = something। আমার সম্ভবত এটি পরীক্ষা করা উচিত :) তবে সম্প্রদায়ের অন্তর্দৃষ্টি পেতে পছন্দ করবেন।
সুপারম্যান

2
উত্তর: না। কারণ: object propertyএকই রেফারেন্সযুক্ত সমস্ত বস্তুর কাছে নতুন মান আপডেটের মান পরিবর্তন করা । এজন্য আপনাকে
কৌনিক

44

সেক্ষেত্রে আপনার ব্যবহারের দরকার নেই angular.copy()

ব্যাখ্যা :

  • =একটি রেফারেন্স প্রতিনিধিত্ব angular.copy()করে যেখানে গভীর অনুলিপি হিসাবে একটি নতুন অবজেক্ট তৈরি করে।

  • ব্যবহারের =অর্থ response.dataহ'ল এর সম্পত্তি পরিবর্তন করার সাথে সাথে এর $scope.exampleবিপরীতে সম্পর্কিত সম্পত্তি পরিবর্তন হবে ।

  • angular.copy()দুটি বস্তু ব্যবহার করা পৃথক থাকবে এবং পরিবর্তনগুলি একে অপরের প্রতিফলিত হবে না।



বুঝতে সহজ। ধন্যবাদ
পুনেতে ভার্মা

7

আমি বলব angular.copy(source);আপনার পরিস্থিতি অপ্রয়োজনীয় যদি পরে আপনি যদি এটি ব্যবহার না করেন তবে এটি কোনও গন্তব্য ছাড়াই angular.copy(source, [destination]);

যদি কোনও গন্তব্য সরবরাহ করা হয় তবে এর সমস্ত উপাদান (অ্যারেগুলির জন্য) বা বৈশিষ্ট্যগুলি (বস্তুর জন্য) মুছে ফেলা হয় এবং তারপরে উত্স থেকে সমস্ত উপাদান / বৈশিষ্ট্যগুলি এতে অনুলিপি করা হয়।

https://docs.angularjs.org/api/ng/function/angular.copy


ধন্যবাদ এস্কো! আমার মাথা সোজা করার চেষ্টা করছে। এর অর্থ কী কোণকোষের জন্য কোনও উপকার হবে: যদি কোনও ভেরিয়েবলের সাথে এর সাথে ইতিমধ্যে ডেটা যুক্ত থাকে, তবে এটি উপাদান / বৈশিষ্ট্যগুলি পুনরায় অর্পণ করার একটি পরিষ্কার উপায়?
সুপারম্যান

1
আপনি angular.copy()অন্য কোনও কোডটিকে সংশোধন করতে বাধা দেওয়ার জন্য কোনও অবজেক্টে ব্যবহার করেন । আসল অবজেক্ট পরিবর্তন হতে পারে তবে আপনার অনুলিপি পরিবর্তনগুলি দেখতে পাবে না। প্রয়োজনে অনুলিপিটি পুনরুদ্ধার করতে পারেন।
এস্কো

1

অ্যাঙ্গুলার.কপি ব্যবহার করার সময়, রেফারেন্সটি আপডেট করার পরিবর্তে একটি নতুন অবজেক্ট তৈরি করা হয় এবং গন্তব্যে নির্ধারিত হয় (যদি কোনও গন্তব্য সরবরাহ করা হয়)। তবে আরও কিছু আছে। একটি গভীর অনুলিপি পরে এই দুর্দান্ত জিনিস আছে।

বলুন আপনার একটি কারখানা পরিষেবা রয়েছে যাতে এমন পদ্ধতি রয়েছে যা কারখানার ভেরিয়েবলগুলি আপডেট করে।

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]

সুতরাং কৌনিক অনুলিপিটি ব্যবহার করার ক্ষেত্রে দুর্দান্ত জিনিসটি হ'ল, গন্তব্যের উল্লেখগুলি পুনরায় স্বনির্ধারিত করে মানগুলি পরিবর্তন না করে মানগুলির পরিবর্তনের সাথে প্রতিফলিত হয়।


1

আমি এর জবাব ইতিমধ্যে জানি, এখনও আমি এটিকে সহজ করার চেষ্টা করছি। সুতরাং কৌনিক কোডিপি (ডেটা) আপনি যেখানে নিজের প্রাপ্ত বস্তুর মূল মানগুলি অবিস্মরণিত / অপরিবর্তিত রেখে পরিবর্তন করতে / পরিবর্তন করতে চান সেই ক্ষেত্রে আপনি ব্যবহার করতে পারেন।

উদাহরণস্বরূপ: ধরুন আমি এপি কল করেছি এবং আমার অরিজিনালবজ পেয়েছি, এখন আমি কিছু ক্ষেত্রে এপি অরিজিনাল ওবিজের মানগুলি পরিবর্তন করতে চাই তবে আমি মূল মূল্যগুলিও চাই তাই আমি যা করতে পারি তা হ'ল, আমি আমার এপিআই অরিজিনালওবিজের একটি অনুলিপি তৈরি করতে পারি ডুপ্লিকেট ওবিজে এবং ডুপ্লিকেট ওজজে এইভাবে আমার আসল ওবিজের মান পরিবর্তন হবে না। সরল কথায় ডুপ্লিকেট ওজেজে সংশোধন আসল ওবিজে প্রতিফলিত হবে না জেএস আপত্তি যেমন আচরণ করে।

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

1

আমি এখানে আমার অভিজ্ঞতাটি ভাগ করে নিচ্ছি, আমি দুটি বস্তুর বৈশিষ্ট্যের তুলনায় অ্যাঙ্গুলার.কপি () ব্যবহার করেছি। আমি ফর্ম উপাদান ছাড়াই বেশ কয়েকটি ইনপুট নিয়ে কাজ করছিলাম, আমি ভাবছিলাম যে কীভাবে দুটি বস্তুর বৈশিষ্ট্যের তুলনা করব এবং ফলাফলের ভিত্তিতে আমাকে সেভ বোতামটি সক্ষম এবং অক্ষম করতে হবে। সুতরাং আমি নীচের হিসাবে ব্যবহার।

আমি ইউজারকপি বলার জন্য আমার ডামি অবজেক্টকে একটি মূল সার্ভার অবজেক্ট ব্যবহারকারী মান নির্ধারণ করেছি এবং ব্যবহারকারীর অবজেক্টের পরিবর্তনগুলি পরীক্ষা করতে ঘড়ি ব্যবহার করেছি।

আমার সার্ভার এপিআই যা সার্ভার থেকে আমাকে ডেটা দেয়:

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);

আমি নিশ্চিত নই তবে দুটি জিনিসের তুলনা করা আমার পক্ষে সর্বদা মাথা ব্যথা ছিল তবে কৌনিক কোডপি () দিয়ে এটি সহজেই চলেছিল।


-2

জাভাস্ক্রিপ্ট ভেরিয়েবলগুলি পাস করে by reference, এর অর্থ এটি:

var i = [];
var j = i;
i.push( 1 );

এখন কারণে by referenceঅংশ i[1], এবং j[1] পাশাপাশি, যদিও শুধুমাত্র iপরিবর্তন করা হয়েছে। এটি কারণ যখন আমরা বলি j = iজাভাস্ক্রিপ্টটি অনুলিপি করে নাi ভেরিয়েবলটি এবং এ্যাসাইন করে না jতবে রেফারেন্সের iমাধ্যমে পরিবর্তনশীল হয় j

কৌনিক অনুলিপি আমাদের এই উল্লেখটি হারাতে দেয় যার অর্থ:

var i = [];
var j = angular.copy( i );
i.push( 1 );

এখন i এখানে সমান [1], jএখনও সমান হয়ে গেলে []।

এমন পরিস্থিতি রয়েছে যখন এই ধরণের copyকার্যকারিতা খুব সহজ।


1
জাভাস্ক্রিপ্ট রেফারেন্স দ্বারা বস্তু পাস । আদিম নয়। আপনার কোড পরীক্ষা করুন।
ওলেগ

হ্যাঁ, ধারণাটি বেশ একই রকম, যদিও সম্পাদিত হয়েছে
গুরামিদেব

1
এবং angular.copyআরও বুদ্ধিমান যে জেএসএন সিরিয়ালাইজেশন কারণ এটি ফাংশনগুলির সাথে ডিল করতে পারে।
ওলেগ

এটি জানতাম না, আমি কসম খেয়েছিলাম যে আমি কৌনিক উত্সের দিকে তাকিয়ে এবং কেবল জেএসএন সিরিয়ালাইজেশন দেখি, তবে আমি এটি আবার পরীক্ষা করে দেখেছি এবং আপনি ঠিক বলেছেন।
গুরমিদেব
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.