Coquelicot
Coquelicot

Reputation: 9093

angular.js: using a directive to insert another directive as an attribute

For example, UI Bootstrap has a directive called 'typeahead' that suggests values for a field. Let's say I want to make a directive that I can use as an attribute for an element that will cause colours to be suggested for that element.

Here's an attempt that fails...

Directive:

angular.module('myApp')
  .directive('suggestcolors', function () {
    return {
      compile: function compile(element, attrs) {
        attrs.$set("typeahead", "color for color in ['red', 'blue', 'green']");
      }
    };
  });

View:

<textarea ng-model="foo" suggestcolors></textarea>

When I inspect the textarea, the attribute has been set, but it doesn't do anything. The same thing happens if I move the change to attrs to the link function. Setting the typeahead attribute directly in the view works as expected:

<textarea ng-model="foo" typeahead="color for color in ['red', 'blue', 'green']"></textarea>

(But I want to be able to insert this attribute dynamically, for reasons of DRY. My actual use case is more complicated than this.)

A similar question was asked here (about dynamically adding ng-click behaviour in the compile step), but never directly answered.

Upvotes: 4

Views: 832

Answers (1)

Steve Kl&#246;sters
Steve Kl&#246;sters

Reputation: 9457

After the compilation, AngularJS only calls $compile for all of the child elements. The element itself is not automatically recompiled, so adding a directive at this stage will not have effect. In your case, I think you can change it from a compile function to a link function (so you get a scope argument), and call $compile(element)(scope) yourself.

See this Fiddle where I have a directive that adds style="color: red", and another directive that "dynamically" adds that directive. It doesn't work, unless I call $compile afterwards.

HTH!

Upvotes: 6

Related Questions