0

ファンシーボックスによってトリガーされているモーダルウィンドウがあります。モーダルが表示されると、fancybox は AppController がリッスンする「modalShown」イベントをブロードキャストします。そのリスナーで、AppController はモーダル ウィンドウのコンテンツで $compile を呼び出し、ModalController を作成し、ビューでイベントを補間し、バインドします。

私の問題は、モーダルを閉じると、モーダル要素が DOM から削除されますが、バインドされた ModalController インスタンスがどこかに永続化していることです。したがって、新しいウィンドウを開くたびに新しいコントローラーを作成すると、これらの孤立したコントローラーはすべて、モーダル ウィンドウ内のイベントに応答します。

私の質問は、 $compile は新しいコントローラーを作成しますが、それへの参照を返さないため、アプリで伝播するこれらの未使用のコントローラーをクリーンアップするにはどうすればよいですか?

関連コード (コーヒー)...

Fancybox ディレクティブ

# sets up the fancybox on each element that triggers the modal...
# <a href="#" fancybox="templateToLoad.html">Trigger Modal</a>
@app.directive 'fancybox', ["$templateCache", "$compile", ($templateCache, $compile) ->
  (scope, element, attrs) ->
    options =
      afterShow : ->
          scope.$root.$broadcast 'modalShown', scope
    element.fancybox options

modal.html

<div class="fancybox-skin">
  <div class="fancybox-outer">
    <div class="fancybox-inner ng-scope">
      <div ng-controller="ModalController" style="..." class="ng-scope">
        <a href="#" ng-click="someAction()">Some Action in ModalController</a>
      </div>
    </div>
  </div>
</div>

モーダルコントローラー

app.controller 'ModalController', [
  '$scope', '$rootScope',($scope, $rootScope) ->

    # keeping track of controllers for debugging
    window.globalCounter ||= 0
    $scope.localCounter = window.globalCounter++

    someAction = () ->
        console.log 'action'

AppController

@app.controller "AppController", [
  "$scope", "$rootScope", "$compile", ($scope, $rootScope, $compile) ->
       $scope.$on 'modalShown', (e, localScope) ->
            console.log('compiling modal contents')
            $compile($('.fancybox-inner'))(localScope)
            $rootScope.$apply() 
4

1 に答える 1

0

あなたModalControllerが持っているのは事実上、関連する機能をセットアップするために実行される単なる機能で$scopeあり、その後、二度と見たり聞いたりすることはありません. まだ残っている機能は、このスコープに残っているか、コントローラーからリークされているため、$scope.$on('$destroy', function() { ... })ブロックでクリーンアップする必要があります。

機能がスコープの$watches または$ons にある場合、スコープが破棄されたときに angular によって自動的にクリーンアップされる必要があります。それらが残っている場合、モーダルが閉じられたときにスコープは破棄されていません。

で親スコープを自分で渡しています$compile($('.fancybox-inner'))(localScope)localScope使用する代わりに、モーダルが閉じているのを確認したときに、この新しいスコープlocalScope.$new()を安全に呼び出すことができます。.$destroy()

余談ですが、AppController機能をfancyboxディレクティブに移動し、これらのブロードキャストを完全に回避することをお勧めします.DOM操作とコンパイルは、コントローラーよりもディレクティブにうまく適合し、作成する必要がある新しいスコープをより簡単に追跡できます.

于 2013-10-10T02:59:22.243 に答える