I have a directive that can be used multiple times on a page. In the template of this directive, I need to use IDs for an input-Element so I can "bind" a Label to it like so:
<input type="checkbox" id="item1" /><label for="item1">open</label>
Now the problem is, as soon as my directive is included multiple times, the ID "item1" is not unique anymore and the label doesn't work correctly (it should check/uncheck the checkbox when clicked).
How is this problem fixed? Is there a way to assign a "namespace" or "prefix" for the template (like asp.net does with the ctl00...-Prefix)? Or do I have to include an angular-Expression in each id-Attribute which consists of the directive-ID from the Scope + a static ID. Something like:
<input type="checkbox" id="{{directiveID}} + 'item1'" /><label for="{{directiveID}} + 'item1'">open</label>
Edit:
My Directive
module.directive('myDirective', function () { return { restrict: 'E', scope: true, templateUrl: 'partials/_myDirective.html', controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) { ... } //controller }; }]);
My HTML
<div class="myDirective"> <input type="checkbox" id="item1" /><label for="item1">open</label> </div>
Types of Directive in AngularJS There are two types of AngularJs directives: Built-in directive.
Directives are markers on the DOM element which tell AngularJS to attach a specified behavior to that DOM element or even transform the DOM element with its children. Simple AngularJS allows extending HTML with new attributes called Directives.
The three types of directives in Angular are attribute directives, structural directives, and components.
What are Directives? At a high level, directives are markers on a DOM element (such as an attribute, element name, comment or CSS class) that tell AngularJS's HTML compiler ( $compile ) to attach a specified behavior to that DOM element (e.g. via event listeners), or even to transform the DOM element and its children.
HTML
<div class="myDirective"> <input type="checkbox" id="myItem_{{$id}}" /> <label for="myItem_{{$id}}">open myItem_{{$id}}</label> </div>
Angular 1.3 introduced a native lazy one-time binding. from the angular expression documentation:
One-time binding
An expression that starts with :: is considered a one-time expression. One-time expressions will stop recalculating once they are stable, which happens after the first digest if the expression result is a non-undefined value (see value stabilization algorithm below).
Native Solution:
.directive('myDirective', function() { var uniqueId = 1; return { restrict: 'E', scope: true, template: '<input type="checkbox" id="{{::uniqueId}}"/>' + '<label for="{{::uniqueId}}">open</label>', link: function(scope, elem, attrs) { scope.uniqueId = 'item' + uniqueId++; } } })
Solution:
.directive('myDirective', function() { var uniqueId = 1; return { restrict: 'E', scope: true, template: '<input type="checkbox"/><label>open</label>', link: function(scope, elem, attrs) { var item = 'item' + uniqueId++; elem.find('input').attr('id' , item); elem.find('label').attr('for', item); } } })
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