AngularJS中元素的指令模板唯一ID

时间:2014-01-09 13:44:23

标签: angularjs templates angularjs-directive uniqueidentifier

我有一个可以在页面上多次使用的指令。在这个指令的模板中,我需要为input-Element使用ID,所以我可以像这样“绑定”一个Label:

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

现在的问题是,只要我的指令被多次包含,ID“item1”就不再是唯一的,并且标签不能正常工作(点击时应选中/取消选中复选框)。

这个问题是如何解决的?有没有办法为模板分配“命名空间”或“前缀”(就像asp.net与ctl00 ...-前缀一样)?或者我必须在每个id-Attribute中包含一个angular-Expression,它包含Scope中的指令ID +静态ID。类似的东西:

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

修改

我的指示

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 个答案:

答案 0 :(得分:87)

<强> HTML

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

答案 1 :(得分:52)

更新

Angular 1.3引入了本机懒惰的一次性绑定。来自angular expression documentation

  

一次性绑定

     

以::开头的表达式被视为a   一次性表达。一次性表达式将停止重新计算一次   它们是稳定的,如果是第一次消化后会发生   表达式结果是一个非未定义的值(请参阅值稳定   算法如下)。

原生解决方案

.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会检查您的ID以进行更改,但您只需将它们设置一次。
  • 检查此模块: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);
        }
    }
})

答案 2 :(得分:2)

我们在范围中添加了BlockId参数,因为我们在Selenium测试中使用了id。它们仍有可能不是独一无二的,但我们更愿意完全控制它们。另一个优点是我们可以为项目提供更具描述性的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>

答案 3 :(得分:1)

除了Ilan和BuriB的解决方案(更通用,哪个好)我找到了解决我特定问题的方法,因为我需要标签的“for”属性的ID。而是可以使用以下代码:

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

以下Stackoverflow-Post帮助:

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