7

We are trying to figure out if there is a way to remove/replace/override a set of directives temporarily whilst in a 'preview' mode.

We have tried removing the module(s) that the directives are contained in, e.g.:

angular.module('myModule', []);

but the directives are still active.

Can anyone help?

james.cookie
  • 357
  • 5
  • 14

3 Answers3

8

Internally AngularJS creates factories from directives, by adding a suffix to the directive name. So you can disable the directives by replacing the factories with noop factories.

var noopDirective = function() { return function () {}; };
if (previewMode) {
    // Disable ngPaste directive
    angular.module('myModule')
        .factory('ngPasteDirective', noopDirective);
}

Make sure this is the last executed code.

guzart
  • 3,700
  • 28
  • 23
  • However, this disables the `ngPaste` directive as a whole, not just the directive inside `myModule` module. For example, supposed that I also define a `ngPaste` directive in `mod2` module. Then, the above code will not only disable `ngPaste` directive in `myModule`, but also the `ngPaste` directive in `mod2`. How can I only disabled the `ngPaste` directive in one module (and also keep the rest of the functionalities) and keep the one in another? BTW, the directive that I want to disable is in a large 3rd-party library, of which I don't want to maintain a modified version. – Rockallite Sep 18 '15 at 07:42
1

As an alternative, consider putting a preview mode into each of the directives. Pass in an attribute to indicate whether the current state is preview or 'live', and conditionalize the directive template with ng-switch.

Tastes vary, but that feels like a more legible approach to me than redefining the directives on-the-fly.

S McCrohan
  • 6,663
  • 1
  • 30
  • 39
  • Unfortunately we have lots of directives and we would be repeating the switch logic in all of them. It would feel cleaner to deal with it all in one place. – james.cookie May 24 '13 at 13:26
  • Hmm. Understood. Would your alternate (preview-mode) versions be static? Could this be accomplished by playing games with the location of the directive templates? (Such as by using templateUrl in the directive definition and making the path dynamic) – S McCrohan May 24 '13 at 13:29
  • I can see how that solution might work, but it feels like a lot more effort than just stashing the directives away and then bringing them back afterwards. – james.cookie May 24 '13 at 13:39
  • Yes. I'm not sure how to accomplish the other, though, so tossing out suggestions in case you end up needing an alternative. Can you use angular.injector() to change the injection list in mid-stream? I've never tried. – S McCrohan May 24 '13 at 13:51
1

In this answer it is described how to remove an angular built-in directive. Based on that idea my suggestion is to do this:

angular.module('myModule', [])
  // ... registering some stuff on the module
  .config(['$provide', function ($provide) {
    // Remove the progress directive of 'ui.bootstrap'.
    // Otherwise we cannot use native progress bar.
    $provide.decorator('{DIRECTIVE_NAME}Directive', ['$delegate', function ($delegate) {
      $delegate.pop();
      return $delegate;
    }]);
  }]);

The $delegate.pop() removes the last directive that has been added with the name {DIRECTIVE_NAME}. So this should be the directive defined by yourself.

stollr
  • 6,534
  • 4
  • 43
  • 59