多次使用指令时附加唯一 ID
Append unique id when directive is used multiple times
我在我的 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>
我能做些什么吗?在另一个 post 中,我读到我可以使用 id="foobar_{{$id}}"
附加一个唯一 ID,但在我的例子中,label
和 textarea
附加了不同的 ID。所以这对我帮助不大。
// 编辑 1: 我的标签和警告正在使用 angular-translate 扩展名进行翻译。这导致每个元素都有不同的 $id
,与预期的不同。
// 编辑 2: 此外,我在每个指令中都有多对标签和文本字段。我终于设法通过维护每个指令 id 并为每对标签和文本字段添加一个唯一前缀来解决我的问题。参见:https://jsfiddle.net/7pxn5cxu/14/
也许我没有完全理解你的问题,但为什么不能使用 $id
作为唯一标识符?
最终工作解决方案
VIEW
<!-- 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
用法更新为从指令 link 函数预生成的唯一 ID。这一代 UUID 是可重用服务 UUIDService
.
的包装器
仍然可以找到以前使用 AngularJS $id
方法的答案 here
VIEW
<!-- 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>
DIRECTIVE/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();
};
}
您可以使用rootscope 来记住上次使用的指令的id,然后递增它。这是一个工作示例(运行示例并检查源代码,所有文本都有不同的 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>
我在我的 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>
我能做些什么吗?在另一个 post 中,我读到我可以使用 id="foobar_{{$id}}"
附加一个唯一 ID,但在我的例子中,label
和 textarea
附加了不同的 ID。所以这对我帮助不大。
// 编辑 1: 我的标签和警告正在使用 angular-translate 扩展名进行翻译。这导致每个元素都有不同的 $id
,与预期的不同。
// 编辑 2: 此外,我在每个指令中都有多对标签和文本字段。我终于设法通过维护每个指令 id 并为每对标签和文本字段添加一个唯一前缀来解决我的问题。参见:https://jsfiddle.net/7pxn5cxu/14/
也许我没有完全理解你的问题,但为什么不能使用 $id
作为唯一标识符?
最终工作解决方案
VIEW
<!-- 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
用法更新为从指令 link 函数预生成的唯一 ID。这一代 UUID 是可重用服务 UUIDService
.
仍然可以找到以前使用 AngularJS $id
方法的答案 here
VIEW
<!-- 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>
DIRECTIVE/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();
};
}
您可以使用rootscope 来记住上次使用的指令的id,然后递增它。这是一个工作示例(运行示例并检查源代码,所有文本都有不同的 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>