Skip to content

Instantly share code, notes, and snippets.

@tbranyen
Last active December 19, 2015 22:59
Show Gist options
  • Save tbranyen/6031797 to your computer and use it in GitHub Desktop.
Save tbranyen/6031797 to your computer and use it in GitHub Desktop.

I have a list of components that are dynamically bound to a parent region via region.components. This is an array that is rendered via ng-repeat. Since they are polymorphic and arbitrary, but all share the same base, I've created a base component directive. However, I want to hook (by component id) a directive up to the same component item. Since the property is dynamically evaluated the second directive never hooks into it.

First attempt:

<div class="{{ component.id }}" base-component ng-repeat="component in components">

and a directive to hook into the className:

app.directive("someID", function() {
  exports.restrict = "C";

  exports.link = function(scope, $el) {
    console.log("Anything?");
  };

  return exports;
});
@btford
Copy link

btford commented Jul 19, 2013

Sorry that you ran into this. At a first glance, this is something that looks like it would work, but doesn't because of some of the complexities in implementing data-binding given the restrictions of the browser.

I'll try to explain why this doesn't work as expected, then provide a solution.

Angular separates the "compilation" (where "compilation" means setting up data-binding, event handlers, etc.) of directives into two phases: compile and link. During the compile phase, you can change the DOM and children of some directive before angular picks up additional directives. This is how ng-repeat is implemented, for instance. After the compile phase, angular won't "see" any new directives that you add to the element. This is typically good for performance (otherwise Angular would be spitting out new DOM elements all the time), but it makes it hard to address your case.

Angular actually provides ngSwitch which is a decent solution to your problem, but not fully generic.

Luckily Angular exposes most of its internal fancy stuff to you, so you can add a feature like this. The solution is to add a linking function that changes, then re-compiles its children. I've implemented a short directive that does just that in this example.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment