I am having trouble with angularjs directives finding child DOM elements with the injected angular element.
For example I have a directive like so:
myApp.directive('test', function () {
return {
restrict: "A",
link: function (scope, elm, attr) {
var look = elm.find('#findme');
elm.addClass("addedClass");
console.log(look);
}
};
});
and HTML such as :
<div ng-app="myApp">
<div test>TEST Div
<div id="findme"></div>
</div>
</div>
I have access to the element which is proffed by adding a class to it. However attempting to access a child element produces an empty array in the var look.
JSFiddle demo is here.
Why is something so trivial not working properly?
In addition to all the built-in AngularJS directives, you can create your own directives. New directives are created by using the . directive function. To invoke the new directive, make an HTML element with the same tag name as the new directive.
AngularJS provides support to create custom directives for following type of elements. Element directives − Directive activates when a matching element is encountered. Attribute − Directive activates when a matching attribute is encountered. CSS − Directive activates when a matching css style is encountered.
Note: When you create a directive, it is restricted to attribute and elements only by default. In order to create directives that are triggered by class name, you need to use the restrict option. The restrict option is typically set to: 'A' - only matches attribute name.
From the docs on angular.element
:
find()
- Limited to lookups by tag name
So if you're not using jQuery with Angular, but relying upon its jqlite implementation, you can't do elm.find('#someid')
.
You do have access to children()
, contents()
, and data()
implementations, so you can usually find a way around it.
You can easily solve that in 2 steps:
1- Reach the child element using querySelector like that:
var target = element[0].querySelector('tbody tr:first-child td')
2- Transform it to an angular.element
object again by doing:
var targetElement = angular.element(target)
You will then have access to all expected methods on the targetElement
variable.
Before the days of jQuery you would use:
document.getElementById('findmebyid');
If this one line will save you an entire jQuery library, it might be worth while using it instead.
For those concerned about performance: Beginning your selector with an ID is always best as it uses native function document.getElementById.
// Fast:
$( "#container div.robotarm" );
// Super-fast:
$( "#container" ).find( "div.robotarm" );
http://learn.jquery.com/performance/optimize-selectors/
jsPerf http://jsperf.com/jquery-selector-benchmark/32
find()
- Limited to lookups by tag name
you can see more information
https://docs.angularjs.org/api/ng/function/angular.element
Also you can access by name or id or call please following example:
angular.element(document.querySelector('#txtName')).attr('class', 'error');
I used
elm.children('.class-name-or-whatever')
to get children of the current element
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With