Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS accessing DOM elements inside directive template

Is there a more "angular" way of selecting DOM elements inside a directive template? For example, say you have this directive:

app.directive("myDirective", function() {     return {         template: '<div><ul><li ng-repeat="item in items"></ul></div>',         link: function(scope, element, attrs) {             var list = element.find("ul");         }     } }); 

I used the jQuery style selector to get a hold of the DOM <ul> element rendered in my template. Is there a better way to do this?

like image 702
Dustin Avatar asked Apr 08 '13 14:04

Dustin


2 Answers

I don't think there is a more "angular way" to select an element. See, for instance, the way they are achieving this goal in the last example of this old documentation page:

{      template: '<div>' +     '<div class="title">{{title}}</div>' +     '<div class="body" ng-transclude></div>' +     '</div>',      link: function(scope, element, attrs) {         // Title element         var title = angular.element(element.children()[0]),         // ...     } } 
like image 153
Blackhole Avatar answered Oct 13 '22 00:10

Blackhole


You could write a directive for this, which simply assigns the (jqLite) element to the scope using an attribute-given name.

Here is the directive:

app.directive("ngScopeElement", function () {   var directiveDefinitionObject = {      restrict: "A",      compile: function compile(tElement, tAttrs, transclude) {       return {           pre: function preLink(scope, iElement, iAttrs, controller) {             scope[iAttrs.ngScopeElement] = iElement;           }         };     }   };    return directiveDefinitionObject; }); 

Usage:

app.directive("myDirective", function() {     return {         template: '<div><ul ng-scope-element="list"><li ng-repeat="item in items"></ul></div>',         link: function(scope, element, attrs) {             scope.list[0] // scope.list is the jqlite element,                            // scope.list[0] is the native dom element         }     } }); 

Some remarks:

  • Due to the compile and link order for nested directives you can only access scope.list from myDirectives postLink-Function, which you are very likely using anyway
  • ngScopeElement uses a preLink-function, so that directives nested within the element having ng-scope-element can already access scope.list
  • not sure how this behaves performance-wise
like image 45
CodeSalad Avatar answered Oct 13 '22 00:10

CodeSalad