多次使用指令时附加唯一ID

时间:2017-06-14 09:40:07

标签: angularjs label html-form uniqueidentifier

我在Angular应用程序中定义了一个自定义指令:

app.directive('foobarDirective', function() {
  return {
    restrict: 'E',
    templateUrl: 'foobar.html'
  };
});

在一个页面中多次使用此指令来创建表单元素。但是,一次只能看到其中一个实例。

现在问题是,我的表单中有标签引用输入字段。由于该指令被多次使用,因此id不再是唯一的,并且标签的for - 机制失败。

<div class="row">
  <div class="col-md-12">
    <label for="foobar" translate="foobar"></label>

    <span class="label label-danger" ng-show="model.foobar.length > 255" translate="warn_too_long"></span>

    <textarea id="foobar" auto-height
      type="text" class="form-control"
      ng-model="model.foobar"></textarea>
  </div>
</div>

我能做些什么吗?在另一篇文章中,我读到我可以使用id="foobar_{{$id}}"附加唯一ID,但在我的情况下,labeltextarea附加了不同的ID。所以这对我没什么帮助。

//编辑1:我的标签和警告正在使用 angular-translate 扩展程序进行翻译。这导致每个元素具有不同的$id,其他预期的元素。

//编辑2:此外,我在每个指令中都有多对标签和文本字段。我终于设法通过维护每个指令id并为每对标签和文本字段添加一个唯一的前缀来解决我的问题。请参阅:https://jsfiddle.net/7pxn5cxu/14/

2 个答案:

答案 0 :(得分:1)

也许我没有完全理解你的问题,但为什么使用$id不可能作为唯一标识符?

最终工作解决方案

查看

<!-- application container -->
<div ng-app="app">

  <!-- directive view template -->
  <script type="text/ng-template" id="foobar.html">
    <p>origId: {{origId}}</p>
    <div class="row">
      <div class="col-md-12">
        <label for="foobar_{{origId}}" class="foobar_{{origId}}" translate="foobar"></label>
        <br />
        <span class="label label-danger foobar_{{origId}}" translate="foobarWarning"></span>
        <br />
        <textarea id="foobar_{{origId}}" auto-height type="text" class="form-control" ng-model="scope.model.foobar" placeholder="id: foobar_{{origId}}"></textarea>
      </div>

      <div class="col-md-12">
        <label for="bar_{{origId}}" class="bar_{{origId}}" translate="bar"></label>
        <br />
        <span class="label label-danger bar_{{origId}}" translate="barWarning"></span>
        <br />
        <textarea id="bar_{{origId}}" auto-height type="text" class="form-control" ng-model="scope.model.bar" placeholder="id: bar_{{origId}}"></textarea>
        <br />
        <strong>Model:</strong> {{scope.model}}
      </div>
    </div>
  </script>

  <foobar-directive></foobar-directive>
  <br/>
  <foobar-directive></foobar-directive>

</div>

<强>指令

angular
.module('app', ['pascalprecht.translate'])

.directive('foobarDirective', function() {
  return {
    restrict: 'E',
    scope : {},
    templateUrl: 'foobar.html',
    link: function(scope, element, attrs) {
        console.log('linked' , scope.$id);
      scope.origId = scope.$id;
    }
  }
});

https://jsfiddle.net/7pxn5cxu/14/

修改

使用$id用法更新指令链接功能中预先生成的唯一ID。这一代UUID是可重用服务UUIDService的包装。

仍然可以找到使用AngularJS $id方法的上一个答案here

查看

<!-- application container -->
<div ng-app="app">

  <!-- directive view template -->
  <script type="text/ng-template" id="foobar.html">
    <div class="row">
      <div class="col-md-12">
        <label for="foobar_{{::id}}">label for foobar_{{::id}}</label>
        <span class="label label-danger"></span>
        <br/>
        <textarea id="foobar_{{::id}}" auto-height type="text" class="form-control" ng-model="model.foobar" placeholder="id : foobar_{{::id}}"></textarea>
        <br/>
        <strong>Model:</strong> {{model}}

      </div>
    </div>
  </script>

  <foobar-directive></foobar-directive>
  <br/>
  <foobar-directive></foobar-directive>

</div>

<强>指令/ SERVICE

angular
  .module('app', [])
  .directive('foobarDirective', foobarDirective)
  .service('UUIDService', UUIDService)

/* directive */
function foobarDirective(UUIDService) {
  var directive = {
    templateUrl: 'foobar.html',
    scope: {
      model: '='
    },
    link: function(scope, element, attrs) {
      scope.id = UUIDService.generateUUID();
    },
    restrict: 'E'
  };
  return directive;    
}

/* UUIDService */
function UUIDService() {
  return {
    generateUUID: generateUUID
  }

  function generateUUID() {
    function s4() {
      return Math.floor((1 + Math.random()) * 0x10000)
        .toString(16)
        .substring(1);
    }
    return s4() + s4() + '-' + s4() + '-' + s4() + '-' +
      s4() + '-' + s4() + s4() + s4();
  };
}

请参阅JSFiddle

答案 1 :(得分:0)

You can use rootscope to remember the id of the directive last used and then increment it. here is a working example(run the example and check the source, all text have different id).

var app = angular.module("app", []);
app
  .controller('Controller', function($scope, $rootScope) {
    $rootScope.directiveID = 0;
  })
  .directive("testDirective", function($rootScope) {
  return {
    controller: function($scope, $rootScope) {
      if ($rootScope.directiveID == undefined) {
        $rootScope.directiveID = 0;
      } else {
        $rootScope.directiveID = $rootScope.directiveID + 1;
      }
    
    
    },
    template: '<div>All of have different div(check in the source)</div>',
    link: function(scope,elem,attr){
          scope.directiveIDS = angular.copy($rootScope.directiveID);
         elem.attr("id","dir_"+scope.directiveIDS);
    }
  };
});
<!DOCTYPE html>

<head>
  <script src="//cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.min.js"></script>
  <script src="script.js"></script>
</head>

<body ng-app="app">
  <div ng-controller="Controller">
    <test-directive></test-directive>
    <test-directive></test-directive>
    <test-directive></test-directive>
    <test-directive></test-directive>

  </div>
</body>

</html>