使用AngularJS,如何一次将所有表单字段设置为$dirty?
我已经使用AngularJS创建了一个HTML表单,并在某些字段中添加了必需的属性。
对于这些字段,我有一个错误消息,显示如果该字段不是$ pristine,也$无效: <input type="text" ng-model="SomeModel.SomeProperty" name="myField" class="input-block-level" required> <p ng-show="frmMyForm.myField.$invalid && !frmMyForm.myField.$pristine" class="error-text">This field is required!</p> 这工作正常但是,如果用户只需跳过必填字段(永远不要将光标放在其中),则该字段始终是原始的,因此即使在单击提交按钮之后,也不会显示错误消息。所以用户面临着无法提交的表单,但没有错误的文字告诉他们为什么。 我的想法是,在提交操作中将所有表单字段设置为$ dirty将触发错误消息,以显示用户简单跳过的任何必填字段。这可能吗?如果是这样,怎么办? 提前致谢。
我们做一些类似于你的答案,我们有一个formSubmitted指令绑定到提交事件,如果触发我们在表单控制器上设置$ submitted变量。这样,您可以以与使用ShowValidationMessages的方式相似的方式使用它,但可重复使用。非常简单的指令:
app.directive('formSubmitted',[function () { return { restrict: 'A',require: 'form',link: function (scope,element,attrs,ctrl) { ctrl.$submitted = false; element.on('submit',function () { scope.$apply(function () { ctrl.$submitted = true; }); }); } }; }]); 您可以将其应用于表单标签本身作为属性。 我们进一步介绍了几个步骤,我们的要求是仅在以下条件成立时才显示验证错误:元素无效,或者表单被提交或输入元素模糊。所以我们结束了另一个指令,要求ngModel在ngModel控制器上设置元素的模糊状态。 最后在html中排除大量重复的锅炉代码,以检查所有这些事情,例如你的ng-show =“frmMyForm.myField。$ invalid&&(!frmMyForm.myField。$ pristine || MyObject.ShowValidationMessages)”我们也将它封装到一个指令中。这个模板指令用Bootstrap锅炉板包装我们的输入元素,并处理所有的验证内容。所以现在我所有的表单输入都遵循这种模式: <div data-bc-form-group data-label="Username:"> <input type="text" id="username" name="username" ng-model="vm.username" data-bc-focus required /> </div> 并且bcFormGroup指令将其转换为启用以下引导的html: <div class="form-group" ng-class="{'has-error': showFormGroupError()}" data-bc-form-group="" data-label="Username:"> <label for="username" class="col-md-3 control-label ng-binding">Username:</label> <div class="col-md-9"> <input type="text" id="username" name="username" ng-model="vm.username" data-bc-focus="" required="" class="ng-pristine form-control ng-valid ng-valid-required"> <span class="help-block ng-hide" ng-show="showRequiredError()">Required</span> </div> </div> 这样可以保持DRY,并为支持哪种类型的输入提供极大的灵活性。 更新: 这是bcFormGroup指令的基本列表。默认模板使用引导的水平形式,但可以适应您的喜好。 app.directive('bcFormGroup',['$compile','$interpolate',function ($compile,$interpolate) { return { restrict: 'A',template: '<div class="form-group" ng-class="{'has-error': showFormGroupError()}">' + '<label for="{{inputId}}" class="col-md-3 control-label">{{label}}</label>' + '<div class="col-md-9">' + '<bc-placeholder></bc-placeholder>' + '</div>' + '</div>',replace: true,transclude: true,require: '^form',scope: { label: '@',inputTag: '@' },formController,transcludeFn) { transcludeFn(function (clone) { var placeholder = element.find('bc-placeholder'); placeholder.replaceWith(clone); }); var inputTagType = scope.inputTag || 'input'; var inputElement = element.find(inputTagType); var fqFieldName = formController.$name + '.' + inputElement.attr('name'); var formScope = inputElement.scope(); if (inputElement.attr('type') !== 'checkbox' && inputElement.attr('type') !== 'file') { inputElement.addClass('form-control'); } scope.inputId = $interpolate(inputElement.attr('id'))(formScope); scope.hasError = false; scope.submitted = false; formScope.$watch(fqFieldName + '.$invalid',function (hasError) { scope.hasError = hasError; }); formScope.$watch(formController.$name + '.$submitted',function (submitted) { scope.submitted = submitted; }); if (inputElement.attr('data-bc-focus') != null || inputElement.attr('bc-focus') != null) { scope.hasBlurred = false; formScope.$watch(fqFieldName + '.$hasBlurred',function (hasBlurred) { scope.hasBlurred = hasBlurred; }); } if (inputElement.attr('required')) { scope.hasRequiredError = false; formScope.$watch(fqFieldName + '.$error.required',function (required) { scope.hasRequiredError = required; }); inputElement.after($compile('<span class="help-block" ng-show="showRequiredError()">Required</span>')(scope)); } if (inputElement.attr('type') === 'email') { scope.hasEmailError = false; formScope.$watch(fqFieldName + '.$error.email',function (emailError) { scope.hasEmailError = emailError; }); inputElement.after($compile('<span class="help-block" ng-show="showEmailError()">Invalid email address</span>')(scope)); } scope.showFormGroupError = function () { return scope.hasError && (scope.submitted || (scope.hasBlurred === true)); }; scope.showRequiredError = function () { return scope.hasRequiredError && (scope.submitted || (scope.hasBlurred === true)); }; scope.showEmailError = function () { return scope.hasEmailError && (scope.submitted || (scope.hasBlurred === true)); }; } }; }]); 更新: 以下指令设置$ focus和$ hasBlurred: app.directive('bcFocus',[function () { var focusClass = 'bc-focused'; return { restrict: 'A',require: 'ngModel',ctrl) { ctrl.$focused = false; ctrl.$hasBlurred = false; element.on('focus',function () { element.addClass(focusClass); var phase = scope.$root.$$phase; if (phase == '$apply' || phase == '$digest') { ctrl.$focused = true; } else { scope.$apply(function () { ctrl.$focused = true; }); } }).on('blur',function () { element.removeClass(focusClass); var phase = scope.$root.$$phase; if (phase == '$apply' || phase == '$digest') { ctrl.$focused = false; ctrl.$hasBlurred = true; } else { scope.$apply(function () { ctrl.$focused = false; ctrl.$hasBlurred = true; }); } }); } }; }]); (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |