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

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

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

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

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

<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>

4 ответов


HTML-код

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

обновление

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

Одна-время обязательного

выражение, которое начинается с :: Считается одноразовое выражение лица. Одноразовые выражения перестанут пересчитываться один раз они стабильны, что происходит после первого дайджеста, если результат выражения-неопределенное значение (см. стабилизация значений алгоритм ниже).

Собственное Решение:

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

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

директива 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>

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

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

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

https://stackoverflow.com/a/14729165/1288552