title: AngularJS directive $destroy
body: <p>I have an angular app setup with <code>ng-view</code>. In one view, in addition to the view itself, there is also a component inside that view that is dynamically loaded. This component is a directive that essentially compiles the contents so the contents can be further hooked with other directives (which it is). The content inside that component is compiled using <code>$compile(element.contents())(scope);</code>.</p>
  <p>As an example:</p>
  <pre class="lang-html prettyprint-override"><code>&lt;ng-view&gt;
    &lt;viewer doc=&quot;getDocument()&quot;&gt;
    &lt;/viewer&gt;
  &lt;/ng-view&gt;
  </code></pre>
  <pre class="lang-js prettyprint-override"><code>angular.directive('viewer', ['$compile', '$anchorScroll', function($compile, $anchorScroll) {
    return function(scope, element, attrs) {
      scope.$watch(
        function(scope) {
          var doc = scope.$eval(attrs.doc);
          if (!doc)
            return &quot;&quot;
          return doc.html;
        },
        function(value) {
          element.html(value);
          $compile(element.contents())(scope);
        }
      );
    };
  }]);
  </code></pre>
  <p>My problem is when I switch routes, I essentially switch <code>ng-view</code> or <code>viewer</code>'s content. The problem I'm having is a memory leak, where in other directives inside the <code>viewer</code> hooks to events and do not clean up when the route is changed.</p>
  <p>One such example is as follows:</p>
  <pre><code>angular.directive('i18n', ['$rootScope', 'LocaleService', function($rootScope, LocaleService) {
    var cleanup;
    return {
      restrict: 'EAC',
      compile: function(element, attrs) {
        var originalText = element.text();
        element.text(LocaleService.getTranslation(originalText, attrs.locale));
        cleanup = $rootScope.$on('locale-changed', function(locale) {
          element.text(LocaleService.getTranslation(originalText, attrs.locale || locale));
        });
      },
      link: function(scope) {
        scope.$on('$destroy', function() {
          console.log(&quot;destroy&quot;);
          cleanup();
        });
      }
    };
  }]);
  </code></pre>
  <p>How do I have it so that these events are properly cleaned up?</p>