2

I'm trying to write an Angular 1 directive that will dynamically add other directives to the element. These other directives are complicated enough to where I don't want to copy and paste their code into this meta directive. I have created a plnkr showing what I'm trying to accomplish here.

Here's a copy of the directive

function myCustomAttribute($compile) {
  var priority = 1001; // greater than ng-repeat
  return {
    restrict: 'A',
    compile: compile,
    priority: priority,
    terminal: true,
  };

  function compile(templateElement, templateAttributes, transcludeFn) {
    var attrValue = templateAttributes[attributeDirectiveName];
    templateAttributes.$set(colorDirectiveName, attrValue);

    var compiled = $compile(templateElement, transcludeFn, priority);
    return function linkFn(scope) {
      compiled(scope);
    };
  }

  function doubleCompile(templateElement, templateAttributes, transcludeFn) {
    var attrValue = templateAttributes[attributeDirectiveName];
    templateAttributes.$set(colorDirectiveName, attrValue);
    templateElement.removeAttr('my-custom-attribute');

    return function linkFn(scope, element, attrs, ctrls, transcludeFn) {
        $compile(element, transcludeFn)(scope);
    };
  }
}

The compile function comes from the angular documentation on the double compilation issue. As the plnkr shows, it has issues when used with a directive that has transclude: true and an isolate scope. It also has issues inside of a nested ng-repeat.

The doubleCompile function comes from Add directives from directive in AngularJS. As the plnkr shows, it has issues with double compiling directives with a higher priority. It also has the same transclude issue.

The plnkr is a minified example of what I'm trying to solve in my application, all code except the myCustomAttribute directive is for highlighting issues. How do I update myCustomAttribute so that it works in all cases?

Community
  • 1
  • 1
Sean Hall
  • 7,629
  • 2
  • 29
  • 44
  • ng-repeat alone is pretty nasty case. The thing you're trying to do will inevitably become messy at some point. Not really practical, probably indicates XY problem. – Estus Flask Dec 14 '16 at 21:31
  • I've been down this road. It would be a great feature, but it's not currently available. If you want it, please sound off [here](https://github.com/angular/angular.js/issues/15270) for angular.js and [here](https://github.com/angular/angular/issues/8785#issuecomment-267099992) for ng2. Also, @estus, I think there are legitimate use cases here. Particularly for isolating functionality into different lego-style directives, while not having to add a million different directives in the dom every time they're used. – Aaron Pool Dec 14 '16 at 21:58
  • @estus This scenario of programmatically adding a directive from a directive was explicitly called out in the Angular documentation I linked to. Also, that question I linked to has been viewed 80k+ times. I don't think this is an XY problem. – Sean Hall Dec 14 '16 at 22:20
  • @AaronPool Those feature requests look like what I'm trying to do. Until those are implemented, the answer to this question may be that this is an open feature request. – Sean Hall Dec 14 '16 at 22:23
  • The question doesn't reflect your particular case. The subject is highly prone to misuse, and there's no sign that it's not a XY problem. 'Generic way' is not a good way of doing the things, because it is not idiomatic. The framework never was designed to do that. For some things you may want to use `ng-include`, for another things it is self-compiling directive. The approach that currently may be considered idiomatic is a directive/component with data bindings and isolated scope. Not a magical thing that can transparently wrap every type of scope and so on. – Estus Flask Dec 14 '16 at 22:40
  • @estus It does sound like the answer to this question is "the framework never was designed to do that". But if you're saying there's no legitimate use case for a generic way to dynamically add directives, then we'll have to agree to disagree. – Sean Hall Dec 14 '16 at 23:15
  • @estus, I understand this feature could be misused, but almost all libraries are prone to misuse. The current state of angular can be used to produce some pretty gross code, if you're very undisciplined. – Aaron Pool Dec 15 '16 at 00:07

0 Answers0