0

I have created a drop down input directive, where the user can pass in a template string to set what the list will actually render. In my example I am passing in <div style="background-color: darkgrey" ng-style="{\'color\': isActive?\'red\':\'blue\'}">{{index}}</div> so it will render the items index number and then color it based on isActive. The index is show properly, and the background color is right but ng-style is being ignored. I create the template in a setTimeout because I have to wait for ng-repeat to render the <li>.

    setTimeout(function() {
         var spanList = elm.find('li');
         for (var index = 0; index < scope.list.length; index++) {
             var listElm = angular.element(spanList[index]);
             var listData = scope.list[index]
             listElm.html($interpolate(scope.listTemplate)(listData));
         }
     }, 0);

I am iterating through the <li> elements and setting the template for each one. I am using $interpolate instead of $compile because using $compile would result in [[Object HTMLDivElement]] and I couldn't figure out why. From what I can tell $compile uses $interpolate anyways, and it works except that ng-style, ng-show, and ng-hide don't work. Why would angular's directives not work with $interpolate?

Here is the working example plunker.

John Slegers
  • 45,213
  • 22
  • 199
  • 169
EasilyBaffled
  • 3,822
  • 10
  • 50
  • 87

2 Answers2

1

$interpolate returns a function which returns a string. It is used to resolve {{bindings}}.

$compile returns a function which returns an html-element. It is used to compile raw (html) strings into html-elements and resolve angular-code inside of this string. $compile uses $interpolate to resolve any bindings inside this string.

In your case you probably want to use $compile and .replaceWith().

Jonathan
  • 3,614
  • 3
  • 21
  • 30
  • Makes sense then the issue remains that $compile is giving me [[Object HTMLDivElement]] instead of the element. – EasilyBaffled Apr 21 '15 at 12:49
  • I have made an edit to my answer, you should look into `replaceWith` in your case (instead of previous append). – Jonathan Apr 21 '15 at 13:00
0

$interpolate is only for interpreting markup (example, "{{firstName}} {{lastName}}"):

AngularJS Documentation

$interpolate is a service used by $compile:

Compiles a string with markup into an interpolation function.

ngStyle, ngShow, etc do not rely on interpolation. Instead they rely on the $parse service to evaluate the AngularJS expression, and determine how to render the behavior.

$compile is appropriate in your scenario because it compiles the template HTML fragment by activating any directives within it, which indirectly calls $parse to evaluate expressions. Remember to append the template to the DOM before you $compile because directives may rely on parent directives higher up the DOM. I recommend the following pattern:

 var e = angular.element(someTemplate); 
 element.append(e);
 $compile(e)($scope);
Michael Kang
  • 52,003
  • 16
  • 103
  • 135