Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Directive template unique IDs for elements in AngularJS

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> 
like image 463
NoRyb Avatar asked Jan 09 '14 13:01

NoRyb


People also ask

How many types of directives are there in AngularJS?

Types of Directive in AngularJS There are two types of AngularJs directives: Built-in directive.

What are directives in AngularJS?

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.

How many types of directives we used in angular explain?

The three types of directives in Angular are attribute directives, structural directives, and components.

What is directive element?

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.


2 Answers

HTML

    <div class="myDirective">         <input type="checkbox" id="myItem_{{$id}}" />         <label for="myItem_{{$id}}">open myItem_{{$id}}</label>     </div> 
like image 150
BuriB Avatar answered Sep 27 '22 19:09

BuriB


UPDATE

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++;         }     } }) 

Only bind once:

  • If you only need to bind a value once you should not use bindings ({{}} / ng-bind)
  • bindings are expensive because they use $watch. In your example, upon every $digest, angular dirty checks your IDs for changes but you only set them once.
  • Check this module: https://github.com/Pasvaz/bindonce

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);         }     } }) 
like image 27
Ilan Frumer Avatar answered Sep 27 '22 19:09

Ilan Frumer