Girish
Girish

Reputation: 558

AngularJS - Run directives explicitly

I'm new to AngularJS and I'm struggling with the following issue.

I need to implement a 3 step workflow as follows:

  1. Make a call to a web service that returns a list of strings. For example, ["apple", "banana", "orange"], etc. I intercept the response and add the angle brackets around each of these strings before I send it to the Views.

  2. For each of the string returned by the service, I have to render

    <apple />
    <banana />
    <orange />
    
  3. Finally, get the actual AngularJS directive corresponding to each of those strings to "execute" (not sure what the right word is) and replace the elements above with the content from the templateUrl property as mentioned in each of their respective directives.

Right now, I'm doing Step 1 and Step 2 above using AngularJS. But I understand that they can be done using plain JavaScript using AJAX calls.

My problem is that the directives don't get "run" or "executed" and I have these tags displayed as plain text on the page -

    <apple />
    <banana />
    <orange />
    
etc.

How do I tell Angular to replace the custom tags with the actual content from their templates?

Thanks for your help.

UPDATE: Here's what the code looks like:

<div class="content" ng-controller="mainController"> 

  <ul class="feeds">

      <li ng-repeat="fruit in fruits">

          <div ng-controller="fruitSpecificController"> {{fruit}} </div>  <!--  This renders <apple />, <banana />, etc. -->       

      </li>

  </ul>

 </div>
 

Also note that each fruit can have its own controller. In the code above, I say "fruitSpecificController", but ideally that would also be generated at runtime. For example, "appleController", "orangeController", etc. and yes, they'll be child controllers of the parent "mainController".

Upvotes: 0

Views: 1023

Answers (2)

CalM
CalM

Reputation: 532

You can use the compile method, but there is a built in directive that will do this for you - if you are willing to load in via a URL.

ng-include

Using ng-include="'/path/to/template.html'" - the evaluated expression URL will be requested and added to the DOM as a child (compiled for you).

You can also cache the templates using $templateCache (if you want to request multiple templates at the same time or cache it for multiple includes).

That would look something like this: $templateCache.put(/path/to/template.html, 'apple html string');

custom directive (with $compile)

Otherwise, if you want to load in and compile a string - use a directive inside of a ng-repeat.

.directive('unsafeHtmlCompile', function($compile){
  return {
    link: function(scope, element, attrs){
      scope.$watch(attrs.unsafeHtmlCompile, function(val){
        if(val !== undefined){
          element.html('');
          var el = angular.element(val);
          element.append(html);
          $compile(el)(scope);
        }
      });
    }
  } 
}

Remember to remove the watcher, if your data won't change :-)

Upvotes: 2

bmceldowney
bmceldowney

Reputation: 2305

You probably just need to use the $compile service. The docs aren't super helpful but the gist is that you call $compile, passing in the DOM element (in your case the parent of your directives). That returns a function that you then execute, passing in the scope that you want to use ($rootscope is probably safe).

$compile(element)($rootScope);

Upvotes: 2

Related Questions