Ответ 1
HTML
<div class="myDirective">
<input type="checkbox" id="myItem_{{$id}}" />
<label for="myItem_{{$id}}">open myItem_{{$id}}</label>
</div>
У меня есть директива, которую можно использовать несколько раз на странице. В шаблоне этой директивы мне нужно использовать идентификаторы для элемента ввода, чтобы я мог "привязать" ярлык к нему так:
<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>
HTML
<div class="myDirective">
<input type="checkbox" id="myItem_{{$id}}" />
<label for="myItem_{{$id}}">open myItem_{{$id}}</label>
</div>
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++;
}
}
})
Решение:
.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 в область видимости, потому что мы используем идентификатор в наших тестах 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>
Помимо решений Ilan и BuriB (которые более общие, что хорошо), я нашел решение моей конкретной проблемы, потому что мне нужны идентификаторы для атрибута "для" метки. Вместо этого можно использовать следующий код:
<label><input type="checkbox"/>open</label>
Следующий Stackoverflow-Post помог: