Angularjs এ অ্যারে গভীরভাবে কীভাবে দেখবেন?


320

আমার সুযোগে অবজেক্টগুলির একটি অ্যারে রয়েছে, আমি প্রতিটি বস্তুর সমস্ত মান দেখতে চাই।

এটি আমার কোড:

function TodoCtrl($scope) {
  $scope.columns = [
      { field:'title', displayName: 'TITLE'},
      { field: 'content', displayName: 'CONTENT' }
  ];
   $scope.$watch('columns', function(newVal) {
       alert('columns changed');
   });
}

কিন্তু আমি যখন মূল্যবোধ, যেমন আমি পরিবর্তন সংশোধন TITLEকরতে TITLE2, alert('columns changed')কখনো popped।

একটি অ্যারের ভিতরে অবজেক্টগুলি গভীরভাবে কীভাবে দেখবেন?

একটি লাইভ ডেমো রয়েছে: http://jsfiddle.net/SYx9b/

উত্তর:


529

আপনি 3 য় যুক্তি সেট করতে পারেন $watchথেকে true:

$scope.$watch('data', function (newVal, oldVal) { /*...*/ }, true);

Https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch দেখুন

কৌণিক 1.1.x যেহেতু আপনি সংগ্রহটি অগভীর ঘড়ির জন্য (কেবলমাত্র "প্রথম স্তরের") সংগ্রহটি দেখতে ব্যবহার করতে পারেন।

$scope.$watchCollection('data', function (newVal, oldVal) { /*...*/ });

Https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch Col લેક્શન দেখুন


2
angular.equalsতৃতীয় যুক্তি যখন বুলিয়ান মান নেয় তখন আপনি কেন ব্যবহার করছেন ?
JayQuerie.com

ধন্যবাদ ট্র্যাভার, দস্তাবেজগুলির ভুল লেখা। আমি উপরের কোডটি আপডেট করেছি এবং আমার কোডটি মিলিয়ে আপডেট করেছি।
পাইরান

36
আপনার এখন 1.1.x এ$watchCollection
জোনাথন রোউনি

39
$watchCollectionআমি এটি যেমন বুঝতে পারি ঠিক তেমন একটি অ্যারে বা অবজেক্টের "প্রথম স্তর" দেখবে। উপরের উত্তরটি যদি আপনার চেয়ে আরও গভীরভাবে দেখার প্রয়োজন হয় তবে এটি সঠিক। bennadel.com/blog/…
ব্লেজমোনজার

1
দুর্দান্ত উত্তর ... আমি যদি পারতাম তবে একাধিক ভোট দিতেন ... :) ধন্যবাদ
জনি-ওয়াই

50

আপনার ঘড়িতে কোনও অবজেক্টকে ডিপ-ডাইভিংয়ের পারফরম্যান্স পরিণতি রয়েছে। কখনও কখনও (উদাহরণস্বরূপ, যখন পরিবর্তনগুলি কেবল ধাক্কা দেয় এবং পপ হয়), আপনি easily সহজেই গণনা করা মান যেমন অ্যারে.লাইনেথ দেখতে চাইতে পারেন।


1
এর বেশি ভোট হওয়া উচিত। গভীর পর্যবেক্ষণ ব্যয়বহুল। আমি বুঝতে পারি ওপি গভীর পর্যবেক্ষণের সন্ধান করছিল, তবে লোকেরা কেবল অ্যারে নিজেই পরিবর্তন হয়েছে কিনা তা জানতে চাইবে এখানে আসতে পারে। দৈর্ঘ্য দেখা অনেক দ্রুত, সেক্ষেত্রে।
স্কট সিলভি

42
এটি একটি মন্তব্য হওয়া উচিত, উত্তর নয়।
ব্লেজমোনজার

1
যেমন @Blazemonger মন্তব্য (উল্লেখ কর্মক্ষমতা বিষয়, $ watchCollection ব্যবহার করে কমিয়ে আনা হবে stackoverflow.com/questions/14712089#comment32440226_14713978 )।
শান দ্য

ঝরঝরে পরামর্শ। এই মন্তব্যটির উত্তর না হওয়ার বিষয়ে, আমার মতে উত্তরের গ্রহণযোগ্যতার মানদণ্ডটি পূরণ করার জন্য পরামর্শটি আরও ভালভাবে জানানো ভাল। আমি মনে করি যে এই পদ্ধতির সাহায্যে প্রশ্নের একটি মার্জিত সমাধান অর্জন করা যেতে পারে।
অ্যামি পেলেগ্রিনি

43

আপনি যদি কেবল একটি অ্যারে দেখতে যাচ্ছেন তবে আপনি কেবল এই বিট কোডটি ব্যবহার করতে পারেন:

$scope.$watch('columns', function() {
  // some value in the array has changed 
}, true); // watching properties

উদাহরণ

তবে এটি একাধিক অ্যারে নিয়ে কাজ করবে না:

$scope.$watch('columns + ANOTHER_ARRAY', function() {
  // will never be called when things change in columns or ANOTHER_ARRAY
}, true);

উদাহরণ

এই পরিস্থিতিটি পরিচালনা করতে, আমি সাধারণত JSON এ দেখতে চাই এমন একাধিক অ্যারে রূপান্তর করি:

$scope.$watch(function() { 
  return angular.toJson([$scope.columns, $scope.ANOTHER_ARRAY, ... ]); 
},
function() {
  // some value in some array has changed
}

উদাহরণ

মন্তব্য @jssebastian সরু আউট হিসাবে, JSON.stringifyবাঞ্ছনীয় হতে পারে angular.toJsonযেমন সদস্যরা '$' এবং সম্ভব অন্যান্য ক্ষেত্রে সঙ্গে হিসাবে ভাল শুরু সব ব্যবস্থা করতে সক্ষম।


আমি $watchএটির তৃতীয় প্যারামিটারটিও দেখতে পাচ্ছি, এটি কি এটি করতে সক্ষম? Pass true as a third argument to watch an object's properties too.দেখুন: cheatography.com/proloser/cheat-sheets/angularjs
Freewind

@ ফ্রিওয়াইন্ড যদি এমন কোনও ঘটনা ঘটে থাকে যেখানে আপনাকে একাধিক অ্যারে দেখার প্রয়োজন হয় এটি এখানে দেখা হিসাবে ব্যর্থ হবে । তবে হ্যাঁ, এটি খুব কার্যকর হবে এবং angular.toJsonএকক অ্যারে ব্যবহারের মতো একই কার্যকারিতা সরবরাহ করে ।
JayQuerie.com

2
কেবল সাবধান থাকুন যে কৌণিক.টোজসন এমন সদস্যদের অন্তর্ভুক্ত বলে মনে হয় না যা '$' দিয়ে শুরু হয়: কৌণিক.টোজসন (world "$ হ্যালো": "বিশ্ব"}) কেবল "{}"} আমি বিকল্প হিসাবে JSON.stringify () ব্যবহার করেছি
jssebastian

@ জেসেবাসিস্টিয়ান ধন্যবাদ - আমি সেই তথ্য অন্তর্ভুক্ত করার জন্য উত্তরটি আপডেট করেছি।
JayQuerie.com

1
আমরা জানতে পারি কোন সম্পত্তি পরিবর্তন হয়েছে?
আশ্বিন

21

এটি লক্ষণীয় যে কৌণিক 1.1.x এবং তারপরে, আপনি এখন $ ঘড়ির চেয়ে $ ওয়াচ কালেকশন ব্যবহার করতে পারেন । যদিও $ ওয়াচ কালেকশনটি অগভীর ঘড়ি তৈরি করে বলে মনে হচ্ছে যাতে এটি আপনার প্রত্যাশা মতো বস্তুর অ্যারে দিয়ে কাজ করবে না। এটি অ্যারেতে সংযোজন এবং মুছে ফেলা সনাক্ত করতে পারে তবে অ্যারের ভিতরে থাকা বস্তুর বৈশিষ্ট্য নয়।


5
$ ওয়াচ কালেকশন কেবল অগভীর দেখায়। সুতরাং আমি এটি যেমন বুঝতে পেরেছি, অ্যারের আইটেমগুলির বৈশিষ্ট্যগুলি (প্রশ্ন হিসাবে) পরিবর্তন করা ইভেন্টটিকে ট্রিগার করবে না।
Tarnschaf

3
এটি একটি মন্তব্য হওয়া উচিত, উত্তর নয়।
ব্লেজমোনজার

18

উদাহরণের সাথে স্কোপ ভেরিয়েবলটি দেখতে পারবেন এমন তিনটি উপায়ে এখানে একটি তুলনা করা হয়েছে:

$ ঘড়ি () দ্বারা ট্রিগার করা হয়েছে:

$scope.myArray = [];
$scope.myArray = null;
$scope.myArray = someOtherArray;

$ ওয়াচ কালেকশন () উপরের সমস্ত কিছু দ্বারা ট্রিগার করা হয়েছে এবং:

$scope.myArray.push({}); // add element
$scope.myArray.splice(0, 1); // remove element
$scope.myArray[0] = {}; // assign index to different value

$ ঘড়ি (... সত্য) উপরের সবকিছু দিয়ে ট্রিগার করা হয়েছে এবং:

$scope.myArray[0].someProperty = "someValue";

শুধু আর একটা জিনিস...

$ ওয়াচ () কেবল তখনই ট্রিগার হয় যখন একটি অ্যারে অন্য অ্যারের সাথে প্রতিস্থাপন করা হয় এমনকি যদি অন্য অ্যারে একই সঠিক সামগ্রী থাকে।

উদাহরণস্বরূপ যেখানে $watch()গুলি হবে এবং $watchCollection()না:

$scope.myArray = ["Apples", "Bananas", "Orange" ];

var newArray = [];
newArray.push("Apples");
newArray.push("Bananas");
newArray.push("Orange");

$scope.myArray = newArray;

নীচে জেএসফিডেলের একটি লিঙ্ক দেওয়া হয়েছে যা সমস্ত "ঘড়ি" ট্রিগার হয়েছিল তা নির্দেশ করার জন্য সমস্ত বিভিন্ন ঘড়ির সংমিশ্রণগুলি এবং আউটপুট লগ বার্তাগুলি ব্যবহার করে:

http://jsfiddle.net/luisperezphd/2zj9k872/


হুবহু, স্পষ্টতই 'ওয়ান মোর থিং' নোট করুন
অ্যান্ডি মা

12

$ ঘড়ি সংগ্রহ আপনি যা করতে চান তা পূরণ করে। নীচে অ্যাংুলারজ ওয়েবসাইট http://docs.angularjs.org/api/ng/type/$rootScope.Scope থেকে অনুলিপি করা একটি উদাহরণ দেওয়া আছে, যদিও এটির সুবিধামত, বিশেষত যখন আপনি একটি বড় সংগ্রহ দেখেন তখন পারফরম্যান্সটি বিবেচনায় নেওয়া উচিত।

  $scope.names = ['igor', 'matias', 'misko', 'james'];
  $scope.dataCount = 4;

  $scope.$watchCollection('names', function(newNames, oldNames) {
     $scope.dataCount = newNames.length;
  });

  expect($scope.dataCount).toEqual(4);
  $scope.$digest();

  //still at 4 ... no changes
  expect($scope.dataCount).toEqual(4);

  $scope.names.pop();
  $scope.$digest();

  //now there's been a change
  expect($scope.dataCount).toEqual(3);

14
ওপিতে বস্তুর একটি অ্যারে নির্দিষ্ট করে। আপনার উদাহরণ স্ট্রিংগুলির একটি অ্যারের সাথে কাজ করে তবে $ ওয়াচ কালেকশনটি অবজেক্টগুলির একটি অ্যারের সাথে কাজ করে না।
কেভিনএল

4

এই সমাধানটি আমার পক্ষে খুব ভাল কাজ করেছে, আমি এটি একটি নির্দেশনায় করছি:

সুযোগ। $ ঘড়ি (attrs.testWatch, ফাংশন () {.....}, সত্য);

সত্যটি বেশ ভাল কাজ করে এবং সমস্ত ছানাগুলির জন্য প্রতিক্রিয়া জানায় (কোনও ক্ষেত্র যুক্ত, মোছা, বা সংশোধন)।

এটির সাথে খেলার জন্য এখানে একটি কার্যনির্বাহী নিমন্ত্রক।

AngularJS এ গভীরভাবে একটি অ্যারে পর্যবেক্ষণ করা হচ্ছে

আমি আশা করি এটি আপনার পক্ষে কার্যকর হতে পারে। আপনার যদি কোনও প্রশ্ন থাকে তবে নির্দ্বিধায় জিজ্ঞাসা করুন, আমি সাহায্য করার চেষ্টা করব :)


4

আমার ক্ষেত্রে, আমার একটি পরিষেবা দেখার দরকার ছিল, এতে একটি ঠিকানা আইটেম রয়েছে যা বেশ কয়েকটি অন্যান্য নিয়ামক দ্বারা দেখেছিল। আমি 'সত্য' পরামিতি যোগ না করা পর্যন্ত আমি একটি লুপে আটকে ছিলাম, যা অবজেক্টগুলি দেখার সময় সাফল্যের চাবিকাঠি বলে মনে হয়।

$scope.$watch(function() {
    return LocationService.getAddress();
}, function(address) {
    //handle address object
}, true);

1

ফাংশনটির objectEqualityপ্যারামিটার (তৃতীয় প্যারামিটার) সেট $watchকরা অবশ্যই অ্যারের সমস্ত বৈশিষ্ট্য দেখার সঠিক উপায়।

$scope.$watch('columns', function(newVal) {
    alert('columns changed');
},true); // <- Right here

পিরান এটির যথেষ্ট উত্তর দেয় এবং $watchCollectionপাশাপাশি উল্লেখ করে ।

আরো বিস্তারিত

আমি ইতিমধ্যে উত্তর দেওয়া প্রশ্নের উত্তর দিচ্ছি কারণ কারণ আমি উল্লেখ করতে চাই যে উইজার্ডওয়ার্ডনার উত্তরটি ভাল নয় এবং ব্যবহার করা উচিত নয়।

সমস্যা হ'ল হজম তাত্ক্ষণিকভাবে ঘটে না। কার্যকর করার আগে তাদের কোডের বর্তমান ব্লকটি শেষ না হওয়া পর্যন্ত তাদের অপেক্ষা করতে হবে। সুতরাং, lengthএকটি অ্যারের দেখুন আসলে কিছু গুরুত্বপূর্ণ পরিবর্তন মিস করতে পারে$watchCollection ধরতে পারে।

এই কনফিগারেশনটি ধরে নিন:

$scope.testArray = [
    {val:1},
    {val:2}
];

$scope.$watch('testArray.length', function(newLength, oldLength) {
    console.log('length changed: ', oldLength, ' -> ', newLength);
});

$scope.$watchCollection('testArray', function(newArray) {
    console.log('testArray changed');
});

প্রথম নজরে, মনে হতে পারে এগুলি একই সাথে আগুন লাগবে, যেমন এই ক্ষেত্রে:

function pushToArray() {
    $scope.testArray.push({val:3});
}
pushToArray();

// Console output
// length changed: 2 -> 3
// testArray changed

এটি যথেষ্ট ভাল কাজ করে তবে এটিকে বিবেচনা করুন:

function spliceArray() {
    // Starting at index 1, remove 1 item, then push {val: 3}.
    $testArray.splice(1, 1, {val: 3});
}
spliceArray();

// Console output
// testArray changed

লক্ষ করুন যে, এর ফলে দৈর্ঘ্য একই এমনকি হয়েছিল, যদিও অ্যারে যাতে ঘড়ি হিসাবে হিসাবে একটি নতুন উপাদান এবং একটি উপাদান হারিয়ে গেছে, $watchউদ্বিগ্ন হয়, lengthপরিবর্তন হয়নি। $watchCollectionযদিও এটি নেওয়া হয়েছে।

function pushPopArray() {
    $testArray.push({val: 3});
    $testArray.pop();
}
pushPopArray();

// Console output
// testArray change

একই ব্লকে একটি পুশ এবং পপ দিয়ে একই ফলাফল ঘটে।

উপসংহার

অ্যারেতে প্রতিটি সম্পত্তি দেখার জন্য, এ ব্যবহার করুন $watch তৃতীয় প্যারামিটার (অবজেক্টএকোয়ালিটি) অন্তর্ভুক্ত করে অ্যারেতে নিজেই করুন এবং সত্যে সেট হয়ে গেল। হ্যাঁ, এটি ব্যয়বহুল তবে কখনও কখনও প্রয়োজনীয়।

অ্যারেটি কখন প্রবেশ করুন / প্রস্থান করবেন তা দেখার জন্য একটি ব্যবহার করুন $watchCollection

একটি ব্যবহার করবেন না $watchউপর lengthঅ্যারের সম্পত্তি। আমি এটি করার জন্য ভাবতে পারি এমন কোনও ঠিক কারণ নেই।


0

$scope.changePass = function(data){
    
    if(data.txtNewConfirmPassword !== data.txtNewPassword){
        $scope.confirmStatus = true;
    }else{
        $scope.confirmStatus = false;
    }
};
  <form class="list" name="myForm">
      <label class="item item-input">        
        <input type="password" placeholder="ใส่รหัสผ่านปัจจุบัน" ng-model="data.txtCurrentPassword" maxlength="5" required>
      </label>
      <label class="item item-input">
        <input type="password" placeholder="ใส่รหัสผ่านใหม่" ng-model="data.txtNewPassword" maxlength="5" ng-minlength="5" name="checknawPassword" ng-change="changePass(data)" required>
      </label>
      <label class="item item-input">
        <input type="password" placeholder="ใส่รหัสผ่านใหม่ให้ตรงกัน" ng-model="data.txtNewConfirmPassword" maxlength="5" ng-minlength="5" name="checkConfirmPassword" ng-change="changePass(data)" required>
      </label>      
       <div class="spacer" style="width: 300px; height: 5px;"></div> 
      <span style="color:red" ng-show="myForm.checknawPassword.$error.minlength || myForm.checkConfirmPassword.$error.minlength">รหัสผ่านต้องมีจำนวน 5 หลัก</span><br>
      <span ng-show="confirmStatus" style="color:red">รหัสผ่านใหม่ไม่ตรงกัน</span>
      <br>
      <button class="button button-positive  button-block" ng-click="saveChangePass(data)" ng-disabled="myForm.$invalid || confirmStatus">เปลี่ยน</button>
    </form>

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