イベントリスナー
まず、2種類の「イベントリスナー」があることを理解することが重要です。
を介して登録されたスコープイベントリスナー$on
:
$scope.$on('anEvent', function (event, data) {
...
});
on
またはを介して要素に接続されたイベントハンドラーbind
:
element.on('click', function (event) {
...
});
$ scope。$ destroy()
ときに$scope.$destroy()
実行され、それは経由して登録されているすべてのリスナーが削除されます$on
その$の範囲をを。
DOM要素や、第2種の添付イベントハンドラーは削除されません。
つまり$scope.$destroy()
、ディレクティブのリンク関数内の例から手動で呼び出してelement.on
も、たとえばを介して接続されたハンドラーやDOM要素自体は削除されません。
element.remove()
remove
はjqLiteメソッド(またはjQueryがAngularjSの前にロードされている場合はjQueryメソッド)であり、標準のDOM Elementオブジェクトでは使用できないことに注意してください。
ときにelement.remove()
その要素を実行され、そのすべての子が一緒にDOMから削除されるすべてのイベントハンドラは、例えば介して結合しますelement.on
。
要素に関連付けられている$ scope は破棄されません。
さらに混乱させるために、というjQueryイベントもあり$destroy
ます。要素を削除するサードパーティのjQueryライブラリを使用している場合、または要素を手動で削除した場合、それが発生したときにクリーンアップを実行する必要がある場合があります。
element.on('$destroy', function () {
scope.$destroy();
});
ディレクティブが「破棄された」場合の対処法
これは、ディレクティブがどのように「破棄される」かによって異なります。
通常のケースではng-view
、現在のビューを変更するためにディレクティブが破棄されます。これが発生すると、ng-view
ディレクティブは関連する$ scopeを破棄し、その親スコープへのすべての参照を切断remove()
して、要素を呼び出します。
これは、次のようにして破棄されたときに、そのビューのリンク関数にthisを含むディレクティブが含まれている場合を意味しますng-view
。
scope.$on('anEvent', function () {
...
});
element.on('click', function () {
...
});
両方のイベントリスナーは自動的に削除されます。
ただし、これらのリスナー内のコードは、たとえば一般的なJSメモリリークパターンを達成した場合など、メモリリークを引き起こす可能性があることに注意することが重要circular references
です。
ビューの変更によりディレクティブが破壊されるというこの通常のケースでも、手動でクリーンアップする必要があるかもしれません。
たとえば、リスナーを次のように登録したとします$rootScope
。
var unregisterFn = $rootScope.$on('anEvent', function () {});
scope.$on('$destroy', unregisterFn);
$rootScope
アプリケーションの存続期間中に破棄されることはないため、これは必要です。
$ scopeが破棄されたときに必要なクリーンアップを自動的に実行しない別のpub / sub実装を使用している場合、またはディレクティブがサービスにコールバックを渡す場合も同様です。
別の状況は、キャンセルすることです$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
やなど、Angularによってディレクティブが「破棄される」ときに何をするかの例ですng-if
。
DOM要素のライフサイクルなどを管理するカスタムディレクティブがある場合は、もちろんより複雑になります。