1

I am wondering what the correct angular way to access the main html template element. I can use getelementbyid and also can access it using attr.$$element[0] but wondering if there is a cleaner way. In the example below I would like the equivalent of the getElementById line.

var app = angular.module('test', []);
app.directive('test', function(){
  return {
    restrict: 'E',
    template: '<canvas id="test-canvas"></canvas>',
    replace: true,
    link: function(scope, elem, attr) {
      // what is angular way of doing this?
      var canvas = initCanvas(document.getElementById("test-canvas")),
      // this works - is this recommended method?
      var canvas = attr.$$element[0];

    }
  };
});
6
  • 1
    If you want to access the 'main html template element' just use the elem param. It's already a reference to the template root element. Commented Jan 28, 2013 at 0:58
  • In the link function, elem is a jQuery (or jQuery lite) wrapped DOM element corresponding to the element the directive is operating on. However, it's possible in some cases that this is a copy of the original element, which may or may not be important for your needs. You can get the actual original element in these rare cases via the compile function of the directive. Commented Jan 28, 2013 at 2:58
  • First thing I tried but it doesn't work. It is the element but not in the same format as that returned by the other options and it's not useable for me - in my case I want to do some canvas work and need to call canvas.getContext('2d') - and getContext is not a function of elem. Commented Jan 28, 2013 at 2:59
  • 3
    Because elem is a jQuery wrapped element. elem[0] returns the raw element that has been wrapped. See stackoverflow.com/a/1677910/62082 Commented Jan 28, 2013 at 3:30
  • 2
    Ahhh!! I got it - it doesnt look like Angular has the .get() function so I guess elem[0] would be the way to go for my needs. If you post your comment as an answer I'll mark it as accepted. Commented Jan 28, 2013 at 3:45

1 Answer 1

1

You should just use elem param like so:

var canvas = elem;

it's a jqLite (jQuery) wrapped element as was mention in the comments.

or

var canvas = elem[0];

to get a raw element.

If you want to get access to children elements and do something with them, you should use angular.element. Angular uses jqLite, it provides limited jQuery methods. You can read further here: Angular's jqLite. For instance, in jqLite you can use find() only with the tag name selector, so if you want to select the child by id you should use something like that:

angular.element(elem[0].querySelector('#your_child')).bind('click', () => {
  elem.toggleClass('some_class');
}

If you are using jQuery, you are able to use find(), then the code will look like that:

elem.find('#your_child').click(() => {
    elem.toggleClass('some_class');
});

Try out console.log(elem) you will see what it is. Hope this helps!

P.S.: Let's say you want to select child elements from the ng-repeat directive. The previous solutions won't work because these elements don't exist yet. All you need to do is to add $timeout like so:

function yourDirective($timeout) {
  return {
    ...
    link: function (scope, elem, attrs) {
      $timeout(() => {
        angular.element(elem[0].querySelectorAll('.your_child')).bind('click', () => {
          // Do something
        }
      });
    }
  }
}

angular
  .module('yourApp')
  .directive('yourDirective', yourDirective);
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.