我正在研究几个组件(指令)以帮助进行表单验证。我希望组件能够了解相关输入元素的状态(例如必需)。例如......
标记:
<form name="editUser">
<control-label input="editUser.name">Name</control-label>
<input type="text" name="name" ng-model="user.name" required/>
</form>
指令:
app.directive("controlLabel", function() {
return {
restrict: "E",
replace: true,
transclude: true,
scope: {
input: "=input"
},
template:
'<label class="control-label">'+
'<span ng-transclude>{{label}}</span>'+
'<span ng-if="input.required"> (required!)</span>'+ // doesn't work?
'</label>'
};
});
输出:
<form name="editUser">
<label>
<span>Name</span>
<span>(required!)</span>
</label>
<input type="text" name="name" ng-model="user.name" required/>
</form>
form.FormController的来源让我相信这是不可能的。有没有办法至少可以访问元素上的attrs?我想过使用装饰器,但到目前为止我还没弄清楚如何做到这一点。
答案 0 :(得分:1)
首先,代码中存在错误。如果您使用transclude
,则必须在指令中声明它,否则您将收到错误。
至于你的问题,在一个指令中,你可以访问DOM元素。对于这个特定的用例,您甚至可以在不创建隔离范围或额外属性的情况下完成:
app.directive("controlLabel", function() {
return {
restrict: "E",
replace: true,
scope: true, // if needed, can also use empty isolated scope { }
transclude: true, // must declare this
template:
'<label class="control-label">' +
'<span ng-transclude>{{label}}</span>' +
'<span ng-if="show"> (required!)</span>' +
'</label>',
link: function(scope, jqElem, attrs) {
// check if next sibling of this directive is required
scope.show = (jqElem.next().attr("required") === 'required');
}
};
});
现在你的控件标签真的很小而且DRY,并且逻辑很好地封装在一个指令中。唯一的要求是您的directive
目标必须是标签的下一个兄弟:
<control-label>Name</control-label>
<input type="text" name="name" ng-model="user.name" required/>
当然,如果需要,您可以使用jquery
- fu更改link
功能以满足您的其他要求。
答案 1 :(得分:1)
您应该使用input.$validators.required
代替input.required
作为:
myApp.directive("controlLabel", function() {
return {
restrict: "E",
replace: true,
transclude: true,
scope: {
input: "=input"
},
template:
'<label class="control-label">'+
'<span ng-transclude>{{label}}</span>'+
'<span ng-if="input.$validators.required"> (required!)</span>'+
'</label>'
};
});