我正在尝试使用生成可编辑列表ng-repeat.我想提醒用户在继续之前更新任何编辑,因此我正在使用动态ng-form创建"嵌套"表单,因为文档说我可以对这些动态创建的输入使用验证.
虽然这似乎在HTML中工作,但我没有看到如何在控制器中访问那些动态创建的表单和相关的验证字段.具体来说,当用户更改输入时,我使用表单$ dirty属性调出一个按钮来告诉用户提交更改.到现在为止还挺好.但是,一旦提交了更改,我希望$setPristine()在该字段上指示已设置更改.在我允许提交主表单之前,可能还有其他方法可以确保在每个输入上提交更改,但这是我能想到的最好的方法.
不幸的是,即使文档说如果我将ng-form命名为它将传播到$scope对象,我找不到访问它的方法. $scope.dynamic_form未定义.
这是一个显示我的意思的plunker:
谢谢!
[编辑]只是为了添加问题,这个特定示例的工作原理是添加到ng-click动态创建的输入上:
ng-click="namesForm.name.$setPristine();clean()"
Run Code Online (Sandbox Code Playgroud)
但我仍然无法访问控制器中动态创建的表单.例如,我希望添加一个观察程序,namesForm.name.$pristine以便我可以设置mainForm.$setValidity(false)子表单,$dirty以防止用户提交主表单,直到所有子表单更改都已提交.
简而言之,问题是如何在父控制器中访问动态创建的嵌套ngForm的验证值?
我需要一种方法来遍历AngularJS表单的已注册控件.本质上,我正在尝试获取所有$ dirty控件,但是没有控件数组(FormController除了包含控件本身之外还有许多不同的属性/函数 - 每个都作为它自己的对象).
我一直在看源代码,我看到controlsFormController中有一个数组正是我正在寻找的数组.有没有办法访问此值,或扩展FormController以包含一个返回此controls数组的函数?
编辑:Plnkr演示
另外,我意识到技术上我可以检查键字符串中的第一个字符"$",但是我希望避免在未来版本的Angular中FormController /指令发生变化的情况.
编辑2:另一个澄清:我所有这一切的目标是能够确定哪些特定字段是$ dirty,是否循环遍历整个控件列表(不包括$ dirty,$ invalid,$ error,$ name,以及生活在Form对象中的其他属性,或者通过扩展FormController并创建一个只返回当前脏的控件(并且不等于它们的起始值)的函数
编辑3:我正在寻找的解决方案需要适用于不同结构的表单/模型.范围上的模型是通过AJAX生成的,因此它们的结构已经设置好了(我想避免为我已经通过AJAX接收的所有数据硬编码新结构).此外,我希望在多个表单/模型中使用此表单提交过程,并且每个表单都具有不同的JSON结构 - 因为它们适用于对象模型中的不同实体.这就是为什么我选择了一种方法来访问controlsFormController中的对象(我将从FormController下面发布代码),因为它是我可以获得所有字段的平面数组的唯一地方.
function FormController(element, attrs) {
var form = this,
parentForm = element.parent().controller('form') || nullFormCtrl,
invalidCount = 0, // used to easily determine if we are valid
errors = form.$error = {},
controls = [];
// init state
form.$name = attrs.name || attrs.ngForm;
form.$dirty = false;
form.$pristine = true;
form.$valid = true;
form.$invalid = false; …Run Code Online (Sandbox Code Playgroud) 我有一个异步验证器:
app.directive('validateBar', ['$http', function($http) {
function link($scope, $element, $attrs, ngModel) {
ngModel.$asyncValidators.myValidator = function(value) {
return $http.get('/endpoint/' + value);
};
}
return {
require: 'ngModel',
link: link
};
}]);
Run Code Online (Sandbox Code Playgroud)
表格模板:
<form name="myForm" ng-submit="foo.$valid && saveForm()">
<input name="bar" ng-model="bar" data-validate-bar>
<p ng-show="myForm.bar.$error.myValidator">Your bar is wrong</p>
<button disabled="myForm.$invalid">
</form>
Run Code Online (Sandbox Code Playgroud)
问题:我希望我的随附表格在myValidator承诺未决时无效.
我知道有两种方法可以在异步验证器处于挂起状态时使表单无效,但它们都是冗长和/或hacky.
// Workaround 1: Mark another validator as invalid while the validator promise is pending.
// I cannot mark 'myValidator' as invalid, gets set to valid immediately by Angular.
app.directive('validateSomething', …Run Code Online (Sandbox Code Playgroud) 我的用例:
我有一个使用ui-router的多步骤表单,如下面的plunkr.我使用ng-form来验证AngularJS提供的信息,比如$ valid,$ dirty等.
每次单击"下一部分"按钮后,我将表单数据发送到服务器以便检索它,以防用户在完成之前退出表单.
如果用户提交两次第一步,我只发送编辑过的数据(如果$ dirty值为true).所有这些都不在plunkr中,我选择向您展示一个简单的表单,但我的表单可以包含一百个字段(收音机,复选框,输入,选择等).
重现问题的步骤(plunkr):
myMultiStepForm.interests.xbox.$dirty = truemyMultiStepForm.interests.xbox.$dirty = false为什么$ dirty值变为false?我想这是因为<ng-form>再次显示并重置所有验证数据.
有办法避免这种情况吗?或者除了<ng-form>处理字段子集的验证之外的其他东西?
这是plunkr:http://plnkr.co/edit/WclqVgiBvUXlsGdSCcj0?p = preview
我一直在玩这个并且无法让它发挥作用.我正在创建一个角形表单,当required属性添加到文本字段时,我能够使验证工作.但是,如果file添加了带有required属性的输入类型,我注意到$error.required文本已显示但即使选择了文件也无法验证.即使添加文件后,它仍然显示为无效.我在jsfiddle中创建了一个示例,所以你可以看一下:http://jsfiddle.net/Alien_time/kxSaz/6/
验证不适用于文件输入吗?如何在使用文件选择时添加必需的选项并进行验证?
javascript validation angularjs angularjs-scope angularjs-ng-form
我有一个嵌套的AngularJS表单,如下所示:
<form name="parentForm" ng-submit="submit()">
<input name="parentInput" type="text">
<ng-include src="childForm.html" ng-form="childForm"></ng-include>
<button type="submit">Submit</submit>
</form>
Run Code Online (Sandbox Code Playgroud)
这是childForm.html
<input name="childInput" type="text">
Run Code Online (Sandbox Code Playgroud)
由于与问题无关的原因,我无法合并父表格和子表单 - 它们需要是两个单独的文件.
现在,当用户单击提交按钮时,验证将正确应用于parentForm和childForm.但是,只有父表单将其$ submitted标志设置为true,这是有问题的,因为我使用它来触发某些错误消息的显示.如果父表单是$ submit,我不希望子表单检查,因为它们是两个单独的文件.我遇到的唯一选择是让child()方法在子窗体上调用$ setSubmitted(),这是很尴尬的,因为现在父窗体需要直接引用子窗体.是否有更好的方法将子表单的$提交为true?
angularjs 1.5中的嵌套表单中存在验证问题,github中存在一个问题.
但是该主题中的2个人提供了解决方案,其中一个人已经开始使用angularjs核心,这是ngFormTopLevel指令,另一个是由一个名为isolate-form的用户提供的.
但是他们都不能处理这种情况而且不能为我工作......至少!
我们假设这个结构:
<ng-form name="X1" novalidate>
<ng-form name="X2" novalidate isolate-form>
<input name="Input01" ng-model="input1" required />
<p ng-show="X2.Input01.$touched && X2.Input01.$invalid">input is not valid</p>
<input name="Input02" ng-model="input2" required />
<input type="button" id="ButtonX2" value="Submit Nested Form" ng-disabled="X2.$invalid" />
</ng-form>
<input name="Input03" ng-model="input3" required ng-minlength="5" />
<input type="button" id="ButtonX1" value="Submit Nested Form" ng-disabled="X1.$invalid" />
</ng-form>
Run Code Online (Sandbox Code Playgroud)
tl; dr:ButtonX1依赖于嵌套表单验证,它不应该!
测试案例1:
第1步:使用任何文本和超过5个字符填充input3.
预期:应启用ButtonX1.
结果:ButtonX1仍处于禁用状态.
测试案例2:
第1步:使用任何文本填充input1.
第2步:使用任何文本填充input2.
预期:应启用ButtonX2.
结果:ButtonX2已启用.
测试案例3:
第1步:使用任何文本和超过5个字符填充input3.
第2步:使用任何文本填充input1.
第2步:使用任何文本填充input2.
预期:应启用ButtonX1和ButtonX2.
结果:ButtonX1和ButtonX2已启用.
另一个问题是当Input01无效时,嵌套表单中的P标签不显示.我尝试了isolateForm和ngFormTopLevel,但他们都遇到了这个问题.
我使用ng-form作为父表单,使用ng-form进行ng-repeat验证.
<div ng-form="form">
<div ng-repeat="field in fields">
<div ng-form="subform"><input...></div>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
并验证如下:
if ($scope.form.subform.$invalid && !$scope.form.subform.$error.required) {
// Do something...
}
Run Code Online (Sandbox Code Playgroud)
(这是非常简化的示例,我为不同的输入类型和不同的名称提供了更多不同的子表单,例如input [text]被命名为TextForm,input [numeric]是NumericForm等.)
如果只有现场,一切都按预期工作.但是,如果ng-repeat生成多个字段,则验证仅触发最后一个子表单,其他子表单将被忽略.
有没有办法循环遍历所有子表单,以检查其中一个是否无效?
此外,我正在标记所有未填写的必填字段,如下所示:
if ($scope.form.$error.required) {
angular.forEach($scope.form.$error.required,
function (object, index) {
$scope.form.$error.required[index].$setDirty();
}
);
}
Run Code Online (Sandbox Code Playgroud)
所以,如果我的字段是这样完成的:
....ng-form="TextForm" ng-class="{ 'has-error': TextForm.$dirty && TextForm.$invalid }"....
Run Code Online (Sandbox Code Playgroud)
并且它标记所有子表单,即使存在许多具有相同名称的子表单.
也许我可以用无效字段做类似的事情?虽然尝试了很多东西但没有任何效果
我有一个通过api提交的表单,可以在post请求完成后立即重用.
对于验证样式要求,我需要删除css类ng-submitted,<form>我似乎找不到用于清除它或重置表单的角度方法.
我试过了:
myForm.$submitted = false;
Run Code Online (Sandbox Code Playgroud)
但是这并没有删除ng-submitted课程
这种方法是否存在角度1.3?
<div class="form-group" ng-class="{'has-error': claimForm.consigneeID.$invalid && claimForm.consigneeID.$touched}">
<label class="label-bold">Consignee ID</label><br>
<input name="consigneeID" ng-model="coId" type="number" ng-maxlength="5" ng-minlength="5" class="form-control input-sm" required>
<div class="help-block" ng-messages="claimForm.consigneeID.$error" role="alert">
<div ng-message="required">Field is required.</div>
<div ng-message="minlength">Too few digits.</div>
<div ng-message="maxlength">Over 5 digits.</div>
</div>
Run Code Online (Sandbox Code Playgroud)
minlength和maxlength错误显示正确的消息并正确设置"has-error"ng-class.但是,如果我将"required"添加到我的字段和相应的消息中,则在重新加载时,"Field is required"始终显示(直到填写).
但是,除非跳过不同的错误,否则不会出现红色的"有错误"类.
我在这里想念的是什么?
javascript twitter-bootstrap angularjs angularjs-ng-form ng-messages