我有以下指令,用于将bootstrap验证项添加到表单中的所有form-group
div:
app.directive('bsValidate',($compile: ng.ICompileService) => {
return {
restrict: "A",
link: (scope, element, attrs, ctrl) => {
function showValidation(formGroupEl: ng.IAugmentedJQuery) {
var input = formGroupEl.find('input[ng-model],select[ng-model],textarea[ng-model]');
if (input.length === 0)
return;
var formNameExt = formGroupEl.closest('form').attr('name') + "." + input.attr('name');
var feedback = $compile('<div ng-messages="' + formNameExt + '" ng-show="' + formNameExt + '.$dirty">')(scope);
feedback.append($compile('<span ng-message="$valid" class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>')(scope));
feedback.append($compile('<span ng-message="$invalid" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>')(scope));
formGroupEl.addClass('has-feedback');
formGroupEl.append(feedback);
scope.$watch(
() => {
var val = scope[formGroupEl.closest('form').attr('name')][input.attr('name')];
return val.$invalid && (val.$touched || val.$dirty);
},(isValid) => {
formGroupEl.toggleClass('has-error', isValid);
});
scope.$watch(
() => {
var val = scope[formGroupEl.closest('form').attr('name')][input.attr('name')];
return val.$valid && (val.$touched || val.$dirty);
},(isValid) => {
formGroupEl.toggleClass('has-success', isValid);
});
}
if (element.get(0).nodeName.toLowerCase() === 'form') {
element.find('.form-group').each((i, formGroup) => {
showValidation(angular.element(formGroup));
});
} else {
showValidation(element);
}
}
};
});
这是我正在使用该指令的Html:
@using (Html.BeginForm("Contact", "Home", FormMethod.Post, new { @class = "form-horizontal", role = "form", name = "comment_form" }))
{
<div class="form-group" bs-validate>
@Html.TextBoxFor(m => m.Name, new { @class = "form-control input-lg focus-start", placeholder = "Your Name", ng_model = "name", required = true })
<div ng-messages="comment_form.Name.$error" ng-show="comment_form.Name.$dirty">
<span class="help-block" ng-message="required">
Your Name is required.
</span>
</div>
</div>
}
运行应用程序时出现以下错误消息:
Error: [$compile:ctreq] Controller 'ngMessages', required by directive 'ngMessage', can't be found!
当我尝试将消息传递元素添加到表单组元素时,会出现错误。如果我评论这些线,一切都按预期工作!此外,我的模板也正常工作:
<div class="form-group has-feedback" ng-class="{'has-error': comment_form.Name.$invalid && (comment_form.Name.$touched || comment_form.Name.$dirty), 'has-success': comment_form.Name.$valid && comment_form.Name.$dirty}">
@Html.TextBoxFor(m => m.Name, new { @class = "form-control input-lg focus-start", placeholder = "Your Name", ng_model = "name", required = true })
<div ng-messages="comment_form.Name" ng-show="comment_form.Name.$dirty">
<span ng-message="$valid" class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>
<span ng-message="$invalid" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>
</div>
<div ng-messages="comment_form.Name.$error" ng-show="comment_form.Name.$dirty">
<span class="help-block" ng-message="required">
Your Name is required.
</span>
</div>
</div>
我需要做些什么才能让$compile
服务在我的指令中工作?
我刚刚找到了一个有效的解决方案,但感觉有些束缚。
如果我用以下内容替换feedback
元素,则可以:
var feedback = $('<div ng-messages="' + formNameExt + '" ng-show="' + formNameExt + '.$dirty">');
var validFeedback = $('<span ng-message="$valid" class="glyphicon glyphicon-ok form-control-feedback" aria-hidden="true"></span>');
var invalidFeedback = $('<span ng-message="$invalid" class="glyphicon glyphicon-remove form-control-feedback" aria-hidden="true"></span>');
formGroupEl.append(feedback);
$compile(feedback)(scope);
feedback.append(validFeedback);
feedback.append(invalidFeedback);
$compile(validFeedback)(scope);
$compile(invalidFeedback)(scope);
有更好的方法吗?