AngularJS - event ঘটনা শ্রোতাদের অপসারণ করে?


200

https://docs.angularjs.org/guide/directive

এই ইভেন্টটি শুনে আপনি ইভেন্ট শ্রোতাদের সরিয়ে ফেলতে পারেন যা মেমরি ফাঁসের কারণ হতে পারে। স্কোপগুলি এবং উপাদানগুলিতে নিবন্ধীকৃত শ্রোতাগুলি ধ্বংস হয়ে যাওয়ার পরে স্বয়ংক্রিয়ভাবে পরিষ্কার হয়ে যায়, তবে আপনি যদি কোনও পরিষেবাতে শ্রোতার নিবন্ধন করেন বা মুছে ফেলা হচ্ছে না এমন কোনও ডোম নোডে কোনও শ্রোতার নিবন্ধভুক্ত করেন, আপনাকে এটিকে নিজেরাই পরিষ্কার করতে হবে বা আপনি একটি মেমরি ফাঁস প্রবর্তন ঝুঁকি।

সেরা অনুশীলন: দিকনির্দেশকদের নিজের পরে পরিষ্কার করা উচিত। আপনি নির্দেশটি সরিয়ে ফেলা হলে ক্লিন-আপ ফাংশন চালানোর জন্য এলিমেন্ট.অন ('$ ধ্বংস', ...) বা স্কোপ can অন ('$ ধ্বংস', ...) ব্যবহার করতে পারেন।

প্রশ্ন:

আমি একটি আছে element.on "click", (event) ->আমার নির্দেশ ভিতরে:

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

উত্তর:


433

ইভেন্ট শ্রোতা

প্রথমে এটি বোঝা গুরুত্বপূর্ণ যে এখানে দুটি ধরণের "ইভেন্ট শ্রোতা" রয়েছে:

  1. স্কোপ ইভেন্ট শ্রোতার মাধ্যমে নিবন্ধিত $on:

    $scope.$on('anEvent', function (event, data) {
      ...
    });
    
  2. ইভেন্ট হ্যান্ডলারগুলি উদাহরণগুলির মাধ্যমে উপাদানগুলির সাথে সংযুক্ত onবা bind:

    element.on('click', function (event) {
      ...
    });
    

$ সুযোগ। $ ধ্বংস ()

কখন $scope.$destroy()মৃত্যুদন্ড কার্যকর করা হবে $onএটি $ সুযোগের মাধ্যমে নিবন্ধিত সমস্ত শ্রোতাকে সরিয়ে ফেলবে ।

এটি ডিওএম উপাদান বা দ্বিতীয় ধরণের কোনও সংযুক্ত ইভেন্ট হ্যান্ডলারগুলি সরাবে না

এর অর্থ হ'ল $scope.$destroy()নির্দেশকের লিঙ্ক ফাংশনের মধ্যে উদাহরণ থেকে ম্যানুয়ালি কল করা উদাহরণস্বরূপ সংযুক্ত কোনও হ্যান্ডলারকে সরিয়ে ফেলবে না element.on, না নিজেই ডিওএম উপাদানটি।


element.remove ()

নোট করুন যে removeএকটি jqLite পদ্ধতি (বা অ্যাংুলারজেএস এর আগে jQuery লোড করা থাকলে jQuery পদ্ধতি) এবং একটি স্ট্যান্ডার্ড ডিওএম এলিমেন্ট অবজেক্টে উপলব্ধ নয়।

কখন element.remove()সেই উপাদানটি কার্যকর করা হবে এবং এর সমস্ত শিশুরা এক সাথে DOM থেকে সরানো হবে উদাহরণস্বরূপ সংযুক্ত সমস্ত ইভেন্ট হ্যান্ডলারগুলি element.on

এটি উপাদানটির সাথে যুক্ত $ সুযোগটি ধ্বংস করবে না

এটিকে আরও বিভ্রান্ত করার জন্য এখানে jQuery ইভেন্টও বলা হয়েছে $destroy। কখনও কখনও তৃতীয় পক্ষের jQuery লাইব্রেরিগুলির সাথে কাজ করার সময় যা উপাদানগুলি সরিয়ে দেয়, বা আপনি যদি সেগুলি ম্যানুয়ালি মুছে ফেলেন, তখন এটি হতে পারে আপনার পরিস্কার করার প্রয়োজন হতে পারে:

element.on('$destroy', function () {
  scope.$destroy();
});

কোনও নির্দেশিকা "ধ্বংস" হয়ে গেলে কী করবেন

এটি কীভাবে নির্দেশকে "ধ্বংস" করা হয় তার উপর নির্ভর করে।

একটি সাধারণ কেসটি হ'ল একটি নির্দেশনা ধ্বংস হয় কারণ ng-viewবর্তমান দৃষ্টিভঙ্গিকে পরিবর্তন করে। যখন এটি ঘটে তখন ng-viewনির্দেশটি সম্পর্কিত $ স্কোপটি ধ্বংস করে দেবে, সমস্ত উল্লেখটিকে তার পিতামাতার স্কোপে বিভক্ত remove()করে এবং উপাদানটিতে কল করে।

এর অর্থ হ'ল যদি সেই ভিউটিতে এর লিঙ্ক ফাংশনে এটির সাথে কোনও নির্দেশনা থাকে যখন এটি দ্বারা ধ্বংস হয়ে যায় ng-view:

scope.$on('anEvent', function () {
 ...
});

element.on('click', function () {
 ...
});

উভয় ইভেন্ট শ্রোতা স্বয়ংক্রিয়ভাবে সরানো হবে।

তবে এটি লক্ষণীয় গুরুত্বপূর্ণ যে এই শ্রোতার অভ্যন্তরের কোডটি এখনও মেমরি ফাঁসের কারণ হতে পারে, উদাহরণস্বরূপ যদি আপনি সাধারণ জেএস মেমরি ফাঁসের ধরণটি অর্জন করেন circular references

এমনকি পরিবর্তনের দৃষ্টিভঙ্গির কারণে কোনও নির্দেশিকা ধ্বংস হওয়ার সাধারণ ক্ষেত্রে এমন কিছু জিনিস রয়েছে যা আপনাকে ম্যানুয়ালি পরিষ্কার করতে হবে।

উদাহরণস্বরূপ, আপনি যদি এখানে শ্রোতা নিবন্ধিত হন $rootScope:

var unregisterFn = $rootScope.$on('anEvent', function () {});

scope.$on('$destroy', unregisterFn);

$rootScopeঅ্যাপ্লিকেশনটির জীবদ্দশায় কখনই ধ্বংস হয় না এটি এটি প্রয়োজন ।

আপনি যদি অন্য কোনও পাব / সাব প্রয়োগকরণ ব্যবহার করছেন যা $ স্কোপটি নষ্ট হয়ে যাওয়ার পরে প্রয়োজনীয় পরিচ্ছন্নতা স্বয়ংক্রিয়ভাবে সম্পাদন করে না বা আপনার নির্দেশিকা যদি পরিষেবাগুলিতে কলব্যাকগুলি পাস করে তবে এটি একই রকম হয়।

অন্য পরিস্থিতি বাতিল $interval/ $timeout:

var promise = $interval(function () {}, 1000);

scope.$on('$destroy', function () {
  $interval.cancel(promise);
});

যদি আপনার নির্দেশিকা ইভেন্টের হ্যান্ডলারগুলিকে বর্তমান দৃশ্যের বাইরের উপাদানের সাথে সংযুক্ত করে তবে আপনাকে সেগুলি ম্যানুয়ালিও পরিষ্কার করতে হবে:

var windowClick = function () {
   ...
};

angular.element(window).on('click', windowClick);

scope.$on('$destroy', function () {
  angular.element(window).off('click', windowClick);
});

নির্দেশগুলি অ্যাঙ্গুলার দ্বারা "ধ্বংস" করা হলে কী করবেন তার কয়েকটি উদাহরণ ছিল, উদাহরণস্বরূপ ng-viewবা দ্বারা ng-if

আপনার যদি কাস্টম দিকনির্দেশনা থাকে যা ডিওএম উপাদানগুলির জীবনচক্র পরিচালনা করে তবে এটি অবশ্যই আরও জটিল হয়ে উঠবে।


4
'$ রুটস্কোপ অ্যাপ্লিকেশনটির জীবদ্দশায় কখনও ধ্বংস হয় না।' : একবার স্পষ্টভাবে আপনি এটি মনে করে। এটাই আমি মিস করছিলাম।
ব্যবহারকারী 276648

@ টাসকেট এখানে একটি ছোট্ট প্রশ্ন, যদি একই নিয়ামক হিসাবে আমাদের কাছে বিভিন্ন ইভেন্টের জন্য একাধিক। রুটস্কোপ have থাকে তবে আমরা $ সুযোগ $ কল করব ("$ ধ্বংস", শ্রোতার নাম 1); প্রতিটি জন্য $ rootScope। different আলাদাভাবে ??
ইয়শিকা গারগ

2
@ যিশিকাগার্গ কেবলমাত্র একটি সহায়ক কার্যকারিতাটি সব শ্রোতাকে ডেকে আনা সম্ভবত সবচেয়ে সহজ হতে চাই। যেমন $ সুযোগ। $ অন ('$ ধ্বংস'), ফাংশন () {শ্রোতার নাম 1 (); ListenerName2 (); ...}); অপ-বিচ্ছিন্ন স্কোপগুলিতে ইভেন্ট হ্যান্ডলারের ক্ষেত্রে $ এর জন্য কি কোনও অতিরিক্ত জটিলতা রয়েছে? বা দ্বিপথের বাইন্ডিংয়ের সাথে স্কোপগুলি বিচ্ছিন্ন করুন?
ডেভিড রাইস

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

@ স্কিচান দুঃখিত, আমি আপনার মন্তব্য মিস করেছি। এটি একটি অনুমান, তবে লোকেরা এর $rootScopeকারণে এটি ব্যবহার করতে পারে : stackoverflow.com/questions/11252780/… নোট করুন যে উত্তরটি শীর্ষে অবস্থিত হিসাবে, এটি পরিবর্তন করা হয়েছে। হ্যাঁ, $scopeসুযোগটি নষ্ট হয়ে গেলে স্বাভাবিকভাবে ইভেন্ট শ্রোতারা স্বয়ংক্রিয়ভাবে পরিষ্কার হয়ে যাবে।
ট্যাসকেট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.