gpt4 book ai didi

angularjs - 使用 AngularJS,如何一次将所有表单字段设置为 $dirty?

转载 作者:行者123 更新时间:2023-12-04 11:09:30 25 4
gpt4 key购买 nike

我使用 AngularJS 创建了一个 HTML 表单并添加了 required某些字段的属性。

对于这些字段,如果该字段不是 $pristine,我会显示一条错误消息。还有 $invalid :

<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 指令绑定(bind)到提交事件,如果被触发,我们会在表单 Controller 上设置 $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 Controller 上元素的模糊状态。

最后摆脱 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 指令将其转换为以下启用 bootstrap 的 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>

这使事情保持干燥,并为支持的输入类型提供了极大的灵活性。

更新:

这是 bcFormGroup 指令的基本列表。默认模板使用 bootstrap 的水平形式,但可以根据您的喜好进行调整。
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: '@'
},

link: function (scope, element, attrs, 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));
};

}
};
}]);

更新:

以下指令设置 $focused 和 $hasBlurred:
app.directive('bcFocus', [function () {
var focusClass = 'bc-focused';
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, 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;
});
}
});
}
};
}]);

关于angularjs - 使用 AngularJS,如何一次将所有表单字段设置为 $dirty?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21466495/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com