Уникальные идентификаторы шаблонов директивы для элементов

У меня есть директива, которую можно использовать несколько раз на странице. В шаблоне этой директивы мне нужно использовать идентификаторы для элемента ввода, чтобы я мог "привязать" ярлык к нему так:

<input type="checkbox" id="item1" /><label for="item1">open</label>

Теперь проблема заключается в том, что, как только моя директива включена несколько раз, идентификатор "item1" больше не уникален, и метка работает некорректно (он должен проверять/снимать флажок при нажатии).

Как эта проблема исправлена? Есть ли способ назначить "пространство имен" или "префикс" для шаблона (например, asp.net с префиксом ctl00...-)? Или мне нужно включить angular -Expression в каждый атрибут id, который состоит из идентификатора директивы из Scope + статического идентификатора. Что-то вроде:

<input type="checkbox" id="{{directiveID}} + 'item1'" /><label for="{{directiveID}} + 'item1'">open</label>

Edit:

Моя директива

module.directive('myDirective', function () {
    return {
        restrict: 'E',
        scope: true, 
        templateUrl: 'partials/_myDirective.html',
        controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
            ...
        } //controller
    };
}]);

Мой HTML

<div class="myDirective">
  <input type="checkbox" id="item1" /><label for="item1">open</label>
</div>

Ответ 1

HTML

    <div class="myDirective">
        <input type="checkbox" id="myItem_{{$id}}" />
        <label for="myItem_{{$id}}">open myItem_{{$id}}</label>
    </div>

Ответ 2

UPDATE

Angular 1.3 ввел нативную ленивую одноразовую привязку. из документации Angular:

Одноразовая привязка

Выражение, начинающееся с:: считается одноразовое выражение. Одноразовые выражения остановят перерасчет один раз они стабильны, что происходит после первого переваривания, если результатом выражения является значение не undefined (см. стабилизацию значения алгоритм ниже).

Родное решение:

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

Только односвязное соединение:

  • Если вам нужно привязать значение только после того, как вы не должны использовать привязки ({{}}/ng-bind)
  • привязки дороги, потому что они используют $watch. В вашем примере, при каждом $digest, angular dirty проверяет ваши идентификаторы на изменения, но вы устанавливаете их только один раз.
  • Проверьте этот модуль: https://github.com/Pasvaz/bindonce

Решение:

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

Ответ 3

Мы добавляем параметр BlockId в область видимости, потому что мы используем идентификатор в наших тестах Selenium, например. У них все еще есть шанс, что они не уникальны, но мы предпочитаем иметь полный контроль над ними. Другим преимуществом является то, что мы можем дать элементу более описательный идентификатор.

Директива JS

module.directive('myDirective', function () {
    return {
        restrict: 'E',
        scope: {
            blockId: '@'
        }, 
        templateUrl: 'partials/_myDirective.html',
        controller: ['$scope', '$element', '$attrs', function ($scope, $element, $attrs) {
            ...
        } //controller
    };
}]);

Директива HTML

<div class="myDirective">
  <input type="checkbox" id="{{::blockId}}_item1" /><label for="{{::blockId}}_item1">open</label>
</div>

Использование

<my-directive block-id="descriptiveName"></my-directive>

Ответ 4

Помимо решений Ilan и BuriB (которые более общие, что хорошо), я нашел решение моей конкретной проблемы, потому что мне нужны идентификаторы для атрибута "для" метки. Вместо этого можно использовать следующий код:

<label><input type="checkbox"/>open</label>

Следующий Stackoverflow-Post помог:

fooobar.com/info/90397/...