Dan
Dan

Reputation: 125

How does AngularJS compile directives?

I'm trying to get a better understanding how AngularJS compiles directives and updates the view.

Here's my specific problem. I have a directive like so:

angular.module('directives', [])

.directive('test', function() {
   return {
      restrict: 'AE',
      scope : { foo : '=' }, 
      template: '<div id={{foo.id}}>{{foo.data}}</div>'
      link: function(scope, element, attrs) {
          document.getElementById(scope.foo.id); /*1*/
      }
    }
 });

At point 1 scope.foo.id is defined. However, the template for the directive has not been compiled yet, so the div id is not set, and getElementById returns null. Once the page is completely rendered, and I look at the compiled template, all of the template id's have been successfully set to foo.id

What am I missing here?

It's also important to note that for my particular case I need to explicitly interact with the template div by it's id.

EDIT: added a fiddle : http://jsfiddle.net/6c4nb/8/

Upvotes: 2

Views: 164

Answers (1)

Pete
Pete

Reputation: 3254

Ok, given the limited information, I was able to get the element working for you. I'm not exactly sure what you want to do, but you need to set the id of the element within the directive.

If someone with better understanding can explain, I'd like to know why the id doesn't get bound within the template. It appears that if you set the id from the directive, it works fine. (jsfiddle)

@Dan I also had to change your ID to use the word test- in front of it because the HTML spec does not allow id's to start with numerical values. According to the spec:

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

var testApp = angular.module('testApp',[]);

testApp.controller('mainCtrl', ['$scope', function($scope) {
    $scope.bar = [
        { id: 1, msg: 'this is a nice message'}, 
        { id: 2, msg: 'this message is also nice'}, 
        { id: 3, msg: 'yet another message'}
    ];
}]); 

testApp.directive('plugin', function() {
    return {
        restrict : 'EA', 
        template: '<div>{{foo.msg}}</div>',
        scope: {'foo': '='},
        compile: function compile(tElement, tAttrs, transclude) {
            return {
                post: function postLink(scope, element, iAttrs, controller) {
                    element.attr('id', 'test-' + scope.foo.id);
                    console.log(document.getElementById('test-' + scope.foo.id));
                    /* This does not provide a null value */
                }
            }
        }
    };
});

Upvotes: 3

Related Questions