Pendengar acara
Pertama, penting untuk dipahami bahwa ada dua jenis "pendengar acara":
Lingkup acara pendengar terdaftar melalui $on
:
$scope.$on('anEvent', function (event, data) {
...
});
Penangan acara dilampirkan ke elemen melalui misalnya on
atau bind
:
element.on('click', function (event) {
...
});
$ scope. $ destroy ()
Ketika $scope.$destroy()
dijalankan, ini akan menghapus semua pendengar yang terdaftar melalui $on
$ scope itu.
Ini tidak akan menghapus elemen DOM atau penangan acara apa pun yang terlampir dari jenis kedua.
Ini berarti bahwa memanggil $scope.$destroy()
secara manual dari contoh dalam fungsi tautan direktif tidak akan menghapus handler yang dilampirkan melalui misalnya element.on
, atau elemen DOM itu sendiri.
element.remove ()
Perhatikan bahwa remove
ini adalah metode jqLite (atau metode jQuery jika jQuery dimuat sebelum AngularjS) dan tidak tersedia pada Objek Elemen DOM standar.
Ketika element.remove()
dijalankan elemen itu dan semua anak-anaknya akan dihapus dari DOM bersama-sama semua penangan acara akan dilampirkan melalui misalnya element.on
.
Itu tidak akan menghancurkan $ scope yang terkait dengan elemen.
Untuk membuatnya lebih membingungkan ada juga acara jQuery yang disebut $destroy
. Terkadang saat bekerja dengan pustaka jQuery pihak ketiga yang menghapus elemen, atau jika Anda menghapusnya secara manual, Anda mungkin perlu melakukan pembersihan saat itu terjadi:
element.on('$destroy', function () {
scope.$destroy();
});
Apa yang harus dilakukan ketika arahan "dihancurkan"
Ini tergantung pada bagaimana arahan "dihancurkan".
Kasus normal adalah bahwa direktif dihancurkan karena ng-view
mengubah tampilan saat ini. Ketika ini terjadi, ng-view
arahan akan menghancurkan $ scope yang terkait, pisahkan semua referensi ke lingkup induknya dan panggil remove()
elemen tersebut.
Ini berarti bahwa jika tampilan tersebut mengandung arahan dengan ini dalam fungsi tautannya ketika dihancurkan oleh ng-view
:
scope.$on('anEvent', function () {
...
});
element.on('click', function () {
...
});
Kedua pendengar acara akan dihapus secara otomatis.
Namun, penting untuk dicatat bahwa kode di dalam pendengar ini masih dapat menyebabkan kebocoran memori, misalnya jika Anda telah mencapai pola kebocoran memori JS yang umum circular references
.
Bahkan dalam kasus normal ini direktif dihancurkan karena perubahan pandangan ada beberapa hal yang mungkin perlu Anda bersihkan secara manual.
Misalnya jika Anda telah mendaftarkan pendengar di $rootScope
:
var unregisterFn = $rootScope.$on('anEvent', function () {});
scope.$on('$destroy', unregisterFn);
Ini diperlukan karena $rootScope
tidak pernah hancur selama masa aplikasi.
Hal yang sama berlaku jika Anda menggunakan implementasi pub / sub lain yang tidak secara otomatis melakukan pembersihan yang diperlukan ketika $ scope dihancurkan, atau jika arahan Anda meneruskan panggilan balik ke layanan.
Situasi lain adalah membatalkan $interval
/ $timeout
:
var promise = $interval(function () {}, 1000);
scope.$on('$destroy', function () {
$interval.cancel(promise);
});
Jika arahan Anda melampirkan penangan acara ke elemen misalnya di luar tampilan saat ini, Anda perlu membersihkannya secara manual juga:
var windowClick = function () {
...
};
angular.element(window).on('click', windowClick);
scope.$on('$destroy', function () {
angular.element(window).off('click', windowClick);
});
Ini adalah beberapa contoh apa yang harus dilakukan ketika arahan "dihancurkan" oleh Angular, misalnya oleh ng-view
atau ng-if
.
Jika Anda memiliki arahan khusus yang mengatur siklus hidup elemen DOM dll. Tentu saja akan menjadi lebih kompleks.
$rootScope
karena ini: stackoverflow.com/questions/11252780/... Perhatikan bahwa ketika jawaban menyatakan di atas, ini telah diubah. Ya, pendengar acara secara normal$scope
akan otomatis dibersihkan saat ruang lingkup tersebut dihancurkan.