Accessing elements in a directive template


#1

Hi,

I have a directive with an external template file. I am trying to get a particular HTML element, for each directive, and modify it. Is this possible?

This directive will go into a ng-repeat, so trying to access it using document.getElementById() only yields the first element(obviously). using document.getElementByClassName(), in a directive seems wasteful (haven’t tried it though).


#2

Hi,
You can try document.querySelectorAll.


#3

But that would retrieve ALL the elements matching the selector. That would be wasteful, since i want to access it from the directive itself. Like when i use the directive in a ng-repeat. There’s got to be some other way?


#4

I’m sorry, I misunderstood you. I thought you wanted to select more elements. If you just need one, you can use document.querySelector


#5

but thats a little bit hacky and inefficient.
Why are you not building a direktive which hangs on exact the element you need?

please try to explain what you want to do… because using native javascript selector function destroys the intention of angularjs ^^


#6

I’m trying to get the directives in a list (ng-repeat), and set the properties of certain elements, in the directive, DOM style.

@bokboki2002
But that will fetch only the first element matching the criteria.

Guys, i’m sorry if i’m not clear enough.

Let me explain again:
consider a directive dirA.
it is referencing a templateUrl containing (example):

<div id="an_id">
</div>

i’m modifying the div, in the directive’s controller, or link function:

.directive('dirA', function() {
    return {
                  controller: function() {
                       var element = document.getElementById('an_id');
                       element.style.width = "100px";
                       element.style.height = "100px";
                   },
                  templateUrl: "template.html"
     };
})

Then, i use this directive with an ng-repeat:

<div ng-repeat="item in items">
     <dir-a></dir-a>
</div>

obviously, only the first div is set, since id is unique and getElementById retrives one element.

is it possible to get the elements using this in the directive?


#7

look into the replace option for direcitve definitions… so you can replace the directive dom-node with the content of the template… so element would be your div.

or use the children selector of jqlite:
https://docs.angularjs.org/api/ng/function/angular.element

add the content of your referenced template to your ng-repeat directly or with ngInclude and add your directive to the dom not you need.

A directive should be placed on the dom-node you need and try not to make ugly handlings at parent nodes


#8

@alterecho, I would do something like this:


#9

yeah but thats totally not how you should do it…

if you want to change elements… write a directive that is working directly on the elements you need


#10

What you are doing is putting directive inside a template and including the template in ng-repeat and you think this is a better way?
I agree to disagree :).


#11

i wanted to keep the wanted structure “alive”… i would never include such a simple template ^^.

if the template is reused somewhere else or is complex i would use it yep.
because loading the template 1 time and use for the other repeats the cached one ;).

so i only wanted to show how to use directives


#12

Thanks guys. I have trouble if i try this:

link: function(scope, element, attribs) {
                var children = element.children();
                for (i in children) {
                    elem = children[0];     //0 here, since there is some other object retrieved too.
                    console.log("id: ", elem.id);      //logs correctly as "an_id"
                    console.log(elem);    //outputs <div style="" id="an_id">
                    elem.style = elem.style.backgroundColor = "purple";
                    console.log(elem);    //outputs <div style="" id="an_id">

                }
                
            }

Why is the style being cleared?? If i don’t remove the line elem.style=... it logs the correct style.


#13

I would not recommend changing the styles directly on element or its children using JS. The better way is to add the CSS class on root element, like in the codepen before (instead of id=‘and_id’) and than use CSS to style individual children, like this:

.main {
  ...
}

.main div {
 ...
}

.main div p {
 ...
}

#14

But what if i want to get a particular tag, and change it’s image?