我的总体目标是将所有可重用的小部件组件化为角度指令,但在尝试制作角度形式错误消息指令时却很困难。我已阅读了很多帖子,但无法看到如何实现这一目标。
我的所有指令都有隔离范围。
我的主要问题是我不知道如何使pattern属性正确绑定到at-error-message指令span元素的ng-show属性,以便错误消息根据模式动态隐藏\ shows
外部HTML是:
<body ng-controller="atVrmLookup">
<ng-form name="vrmForm" novalidate>
<at-input name="registration" label="Registration" required model="vrmLookup.registration" minlength="3"></at-input>
<at-error-message pattern="vrmForm.registration.$error.required" message="Please enter a registration"></at-error-message>
</ng-form>
</body>
atInput指令是
uiComponents.directive('atInput', function () {
return {
// use an inline template for increased
template: '<div><label>{{label}}</label><div><input name="{{name}}" type="text" ng-model="model" ng-minlength="{{minlength}}"/></div></div>',
// restrict directive matching to elements
restrict: 'E',
scope: {
name: '@',
label: '@',
minlength: '@',
model:'=model'
},
compile: function (element, attr, scope) {
var input = element.find('input');
if (!_.isUndefined(attr.required)) {
input.attr("required", "true");
}
},
controller: function ($scope, $element, $attrs) {
// declare some default values
}
};
});
atErrorMessageDirective是
uiComponents.directive('atErrorMessage', function () {
return {
// use an inline template for increased
template: '<span class="error" ng-show="pattern">{{message}}</span>',
// restrict directive matching to elements
restrict: 'E',
scope: {
message: '@',
pattern: '='
},
controller: function ($scope, $element, $attrs) {
// declare some default values
}
};
});
以下是了解问题的傻瓜。
http://plnkr.co/edit/5tdsqSXg0y5bfQqJARFB
任何帮助都将不胜感激。
答案 0 :(得分:1)
输入名称不能是有角度的绑定表达式。而是使用模板函数,并构建模板字符串:
template: function($element, $attr) {
return '<div><label>{{label}}</label><div>' +
'<input name="' + $attr.name + '" type="text" ng-model="model" ng-minlength="{{minlength}}"/>' +
'</div></div>';
}
替代解决方案
实现dynamic-name指令,并使用angular form指令公开的API以编程方式设置ngModel的名称,并将ngModel控件添加到表单中:
.directive("dynamicName",[function(){
return {
restrict:"A",
require: ['ngModel', '^form'],
link:function(scope,element,attrs,ctrls){
ctrls[0].$name = scope.$eval(attrs.dynamicName) || attrs.dynamicName;
ctrls[1].$addControl(ctrls[0]);
}
};
}])
然后在你的模板中:
template: '<div><label>{{label}}</label><div><input dynamic-name="{{name}}" type="text" ng-model="model" ng-minlength="{{minlength}}"/></div></div>',
注意:此解决方案有效,因为幸运的是,ngForm提供了编程访问来自定义其行为。如果ngForm的控制器没有公开API,那么你可能已经是SOL了。考虑从您自己的自定义指令控制器公开的API,这是一种很好的做法 - 您永远不会知道其他指令如何使用它。