Angularjs指令访问容器元素的属性

时间:2013-12-07 10:59:23

标签: javascript angularjs angularjs-directive

我正在尝试制作一个自动为输入字段添加标签的指令,所以我想要实现的是:

<!-- angular -->
<label-input label="some label:" id="some-random-id">
  <input type="text" maxlength="5" />
</label-input>

并将其转换为:

<!-- html -->
<label for="some-random-id">
  some label: <input id="some-random-id" type="text" maxlength="5" />
</label>

我已经走到这一步了,但是我不知道你应该怎么修改通过翻译添加的元素,或者你应该是否应该这样做?

app.directive('labelInput', function () {
  return {
    restrict: 'E',
    transclude: true,
    scope: {
      id: '@',
      label: '@',
    },
    template: '<label for="{{id}}">{{label}}</label><span ng-transclude></span>',
  };
});

我主要担心的是我不想写两次id,最好是,如果没有传递id,它会被自动生成,也就是说:

<label-input><input type="text" /></label-input>

转换为:

<label for="some-random-id-1231231"></label><input type="text" id="some-random-id-1231231" />

1 个答案:

答案 0 :(得分:2)

您可以在指令中添加一个链接函数,您可以(并且应该)修改和/或控制指令的行为及其DOM表示。有关更多信息,请访问the docs on directives

给出以下标记:

<body ng-app="myModule">
    <div>
        <label-input label="some label with a given id:" id="some-random-id">
              <input type="text" maxlength="5" />
        </label-input>
    </div>
    <div>
        <label-input label="another label with a random id:">
              <input type="text" maxlength="5" />
        </label-input>
    </div>
</body> 

根据您的需要行事的指令可能如下所示:

var app = angular.module('myModule', [])
app.directive('labelInput', function () {
  return {
    restrict: 'E',
    transclude: true,
    scope: {
      id: '@',
      label: '@',
    },
    template: '<label for="{{id}}">{{label}}</label><span ng-transclude></span>',
    link: function (scope, element, attrs) {
        scope.id = attrs.id || 'input-id-'+ new Date().getTime().toString()
        element.find('input').attr('id', scope.id);
    }
  }}); 

小提琴:http://jsfiddle.net/uz76h/

请注意,ID生成远非防弹。

修改:按照以下评论中的要求进行扩展

没有包含:

 app.directive('labelInput', function () {
  return {
    restrict: 'E',
    scope: {
      id: '@',
      label: '@',
    },
    link: function (scope, element, attrs) {
        scope.id = attrs.id || 'input-id-'+ new Date().getTime().toString()
        element.prepend('<label for="'+scope.id+'">'+scope.label+'</label>');            
        element.find('input').attr('id', scope.id)
    }
  }});