core
core

Reputation: 33079

Using $compile in directive

I have a directive that is only suppose to do something when $compile.debugInfoEnabled() returns true.

However, $compile is undefined:

angular
    .module('myapp', [])
    .directive('myDebugThing', [
        '$compile',
        function ($compile) {
            return {
                restrict: 'A',
                priority: Number.MAX_SAFE_INTEGER || Math.pow(2, 53) - 1,
                link: function (scope, element, attrs) {
                    // only run in local environment, not deployed ones
                    if (!$compile.debugInfoEnabled()) {
                        return;
                    }

                    // perform magic trick using element.isolateScope() and other stuff
                    ...
                }
            };
        }
    ])
;

I've tried replacing $compile is $compileProvider but get the same undefined for both $compile and $compileProvider injections.

How am I suppose to perform my check?

Upvotes: 0

Views: 409

Answers (2)

TekTimmy
TekTimmy

Reputation: 3225

In the documentation they use the $compileProvider and $compile in the configuration function of the module:

<script>
  angular.module('compileExample', [], function($compileProvider) {
    // configure new 'compile' directive by passing a directive
    // factory function. The factory function injects the '$compile'
    $compileProvider.directive('compile', function($compile) {
      // directive factory creates a link function
      return function(scope, element, attrs) {
        scope.$watch(
          function(scope) {
             // watch the 'compile' expression for changes
            return scope.$eval(attrs.compile);
          },
          function(value) {
            // when the 'compile' expression changes
            // assign it into the current DOM
            element.html(value);

            // compile the new DOM and link it to the current
            // scope.
            // NOTE: we only compile .childNodes so that
            // we don't get into infinite loop compiling ourselves
            $compile(element.contents())(scope);
          }
        );
      };
    });
  })
  .controller('GreeterController', ['$scope', function($scope) {
    $scope.name = 'Angular';
    $scope.html = 'Hello {{name}}';
  }]);
</script>
<div ng-controller="GreeterController">
  <input ng-model="name"> <br/>
  <textarea ng-model="html"></textarea> <br/>
  <div compile="html"></div>
</div>

The config function documentation says: Use this method to register work which needs to be performed on module loading. Which I understand as registering a new directive working with the compiler can only be done there..

Upvotes: -1

glennanthonyb
glennanthonyb

Reputation: 1885

From what I can see in the $compileProvider source the debugInfoEnabled value is not available after $compileProvider has initialised.

As it's something you set

$compileProvider.debugInfoEnabled(true)

Could you set that somewhere accessible to the application - dare I say a global (don't hurt me). Or, slightly less controversial, store debug information inside of another provider that does have a public debugInfoEnabled property or function. Please note, I haven't tested this code, and it's just to get the point across.


(function(app) {

  app.provider('debugInfoProvider', debugInfoProvider);

  function debugInfoProvider() {
    var _debugInfoEnabled = false;

    this.debugInfoEnabled = function debugInfoEnabled(enabled) {
      _debugInfoEnabled = enabled;
    };

    this.$get = function() {
      return {
        isDebugInfoEnabled: function() {
          return _debugInfoEnabled;
        }
      };
    }
  }

  app.config(config);

  function config(debugInfoProvider, $compileProvider) {
    var debugInfoEnabled = true;
    debugInfoProvider.debugInfoEnabled(debugInfoEnabled);
    $compileProvider.debugInfoEnabled(debugInfoEnabled);
  }

  app.directive('myDebugThing', [
    '$compile',
    function(debugInfo) {
      return {
        restrict: 'A',
        priority: Number.MAX_SAFE_INTEGER || Math.pow(2, 53) - 1,
        link: function(scope, element, attrs) {
          // only run in local environment, not deployed ones
          if (!debugInfo.isDebugInfoEnabled()) {
            return;
          }
        }
      };
    }
  ])

}(angular.module('app')));

Upvotes: 2

Related Questions