AskOcre
AskOcre

Reputation: 115

Passing an Angular expression to a custom directive

I have this directive:

    gymApp.directive('ngListar', function() { 
      return { 
        templateUrl: function(elem, attr){
          console.log(attr.type);
          return 'js/directives/listar-'+attr.type+'.html';
        }
      }; 
    });

The idea is that when I call the directive a parameter is added that will determine which html file to call, so the html looks like this

    <tr ng-listar type="{{list.tipo}}"></tr>

But the log prints out {{list.tipo}} instead of the value inside of it. Is there a way I can pass the expression as a parameter?

Upvotes: 2

Views: 1959

Answers (2)

Pankaj Chauhan
Pankaj Chauhan

Reputation: 356

Instead of getting in attr, Print your scope variable.

app.directive("insertAfter", function(){
    return {
        scope: {
            content: "@",
            type: "@"
        }, 
        link: function(scope, element, attrs){
            console.log(scope.type);
            element.after(scope.content);
        }
    }
  });

Upvotes: 0

Matthew Green
Matthew Green

Reputation: 10401

The reason this doesn't work is described in the docs for the templateUrl (emphasis mine):

Because template loading is asynchronous the compiler will suspend compilation of directives on that element for later when the template has been resolved. In the meantime it will continue to compile and link sibling and parent elements as though this element had not contained any directives.

The variable binding that Angular does is a directive and therefore won't complete until after your directive is done loading its template.

As for a work-around, you might need to manually call $compile yourself instead of relying on templateUrl to do it for you. See the second note under $compile for that.

Borrowing some code from this answer, you can do the following in your directive if you use $templateRequest:

link: function(scope, element, attr){
   $templateRequest('js/directives/listar-' + attr.type + '.html').then(function(html){
      var template = angular.element(html);
      element.append(template);
      $compile(template)(scope);
   });
};

$templateCache and $http.get should also be options with very similar code to the above. That should get around the issue of the value not being interpolated yet.

Upvotes: 1

Related Questions