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


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

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

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

как эта проблема исправлена? Есть ли способ назначить "пространство имен" или "префикс" для шаблона (например asp.net делает с ctl00...- Префикс)? Или мне нужно включить угловое выражение в каждый 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 65

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 в область, потому что мы используем идентификатор в наших тестах Селена, например. Есть еще шанс, что они не уникальны, но мы предпочитаем иметь полный контроль над ними. Еще одно преимущество заключается в том, что мы можем дать этому элементу более описательный код.

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