Validation AngularJS:与服务器端验证集成
我有一个angular应用程序,其中包含一个从示例中选取的保存按钮:Validation AngularJS:与服务器端验证集成,validation,angularjs,Validation,Angularjs,我有一个angular应用程序,其中包含一个从示例中选取的保存按钮: <button ng-click="save" ng-disabled="form.$invalid">SAVE</button> 保存 这对于客户端验证非常有效,因为当用户修复问题时,form.$invalid将变为false,但我有一个电子邮件字段,如果其他用户使用相同的电子邮件注册,该字段将设置为无效 一旦我将电子邮件字段设置为无效,我就无法提交表单,用户也无法修复该验证错误。因此,现在我不能
<button ng-click="save" ng-disabled="form.$invalid">SAVE</button>
保存
这对于客户端验证非常有效,因为当用户修复问题时,form.$invalid
将变为false,但我有一个电子邮件字段,如果其他用户使用相同的电子邮件注册,该字段将设置为无效
一旦我将电子邮件字段设置为无效,我就无法提交表单,用户也无法修复该验证错误。因此,现在我不能再使用表单。$invalid
来禁用我的提交按钮
必须有更好的方法这是另一种情况,自定义指令是您的朋友。您需要创建一个指令,并将$http或$resource注入其中,以便在验证时向服务器回拨 自定义指令的一些伪代码:
app.directive('uniqueEmail',函数($http){
变形虫;
返回{
限制:“A”,
要求:'ngModel',
链接:函数(作用域、元素、属性、控制){
//当范围更改时,请检查电子邮件。
范围$watch(attr.ngModel,function(value){
//如果以前有过尝试,请停止。
如果(toId)清除超时(toId);
//开始一次新的尝试,但要延迟,以防止
//变得太“健谈”。
toId=setTimeout(函数(){
//调用返回{isValid:true}或{isValid:false}的某个API
$http.get('/Is/My/EmailValid?email='+value)。成功(函数(数据){
//设置字段的有效性
ctrl.$setValidity('uniqueEmail',data.isValid);
});
}, 200);
})
}
}
});
下面是您在加价中如何使用它:
电子邮件不是唯一的。
编辑:上面发生的事情的一个小解释
- 触发$watch时,它通过$HTTPAjax调用向服务器发出调用,并传递电子邮件
- 服务器将检查电子邮件地址并返回一个简单的响应,如{isValid:true}
- 该响应用于设置控件的有效性
EDIT2:这也允许您使用表单。$invalid禁用提交按钮。我创建了plunker,其解决方案非常适合我。它使用自定义指令,但用于整个表单,而不是单个字段
我不建议为服务器验证禁用提交按钮。好。如果有人需要工作版本,请点击此处: 从文件:
$apply() is used to enter Angular execution context from JavaScript
(Keep in mind that in most places (controllers, services)
$apply has already been called for you by the directive which is handling the event.)
这让我觉得我们不需要:$scope.$apply(函数){
,否则它会抱怨$digest
app.directive('uniqueName', function($http) {
var toId;
return {
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
//when the scope changes, check the name.
scope.$watch(attr.ngModel, function(value) {
// if there was a previous attempt, stop it.
if(toId) clearTimeout(toId);
// start a new attempt with a delay to keep it from
// getting too "chatty".
toId = setTimeout(function(){
// call to some API that returns { isValid: true } or { isValid: false }
$http.get('/rest/isUerExist/' + value).success(function(data) {
//set the validity of the field
if (data == "true") {
ctrl.$setValidity('uniqueName', false);
} else if (data == "false") {
ctrl.$setValidity('uniqueName', true);
}
}).error(function(data, status, headers, config) {
console.log("something wrong")
});
}, 200);
})
}
}
});
HTML:
我在一些项目中需要它,所以我创建了一个指令。最后,我花了一点时间将它放到GitHub上,供任何想要加入解决方案的人使用 功能:
- 用于对任何文本或密码输入进行Ajax验证的插件解决方案
- 使用Angulars内置验证和cab,可在formName.inputName.$error.ngRemoteValidate访问
- 限制服务器请求(默认为400毫秒),并可使用
ng remote throttle=“550”
- 允许使用
ng remote method=“GET”
<h3>Change password</h3>
<form name="changePasswordForm">
<label for="currentPassword">Current</label>
<input type="password"
name="currentPassword"
placeholder="Current password"
ng-model="password.current"
ng-remote-validate="/customer/validpassword"
required>
<span ng-show="changePasswordForm.currentPassword.$error.required && changePasswordForm.confirmPassword.$dirty">
Required
</span>
<span ng-show="changePasswordForm.currentPassword.$error.ngRemoteValidate">
Incorrect current password. Please enter your current account password.
</span>
<label for="newPassword">New</label>
<input type="password"
name="newPassword"
placeholder="New password"
ng-model="password.new"
required>
<label for="confirmPassword">Confirm</label>
<input ng-disabled=""
type="password"
name="confirmPassword"
placeholder="Confirm password"
ng-model="password.confirm"
ng-match="password.new"
required>
<span ng-show="changePasswordForm.confirmPassword.$error.match">
New and confirm do not match
</span>
<div>
<button type="submit"
ng-disabled="changePasswordForm.$invalid"
ng-click="changePassword(password.new, changePasswordForm);reset();">
Change password
</button>
</div>
</form>
更改密码
现在的
要求的
当前密码不正确。请输入您的当前帐户密码。
新的
证实
新建和确认不匹配
更改密码
感谢从本页了解到的有关
选项指令,这比我不太喜欢的稍微少一点,因为每个字段都要编写指令。
模块是相同的-通用解决方案
但是在模块中,我遗漏了一些东西-检查字段中的一些规则。然后我只是修改了模块
为俄文自述道歉,最终会有所改变。
我急忙与大家分享突然有人有同样的问题。
是的,我们聚集在这里就是为了这个 负载:
<script type="text/javascript" src="../your/path/remoteValidate.js"></script>
HTML
<input type="text" name="login"
ng-model="user.login"
remote-validate="( '/ajax/validation/login', ['not_empty',['min_length',2],['max_length',32],'domain','unique'] )"
required
/>
<br/>
<div class="form-input-valid" ng-show="form.login.$pristine || (form.login.$dirty && rv.login.$valid)">
From 2 to 16 characters (numbers, letters and hyphens)
</div>
<span class="form-input-valid error" ng-show="form.login.$error.remoteValidate">
<span ng:bind="form.login.$message"></span>
</span>
但这并不能真正解决我的问题。他们仍然有可能提交一封非唯一的电子邮件,我仍然必须在服务器端验证它,在这一点上,我仍然必须显示客户端错误,而不是通过此指令?但我离题了,如果他们能够提交一封无效的电子邮件,提交将返回一个错误并标记为表单无效,在这一点上在提交表单之前,他们将被迫使用此指令将电子邮件字段标记为有效。此指令将异步向服务器发送请求,服务器将检查电子邮件,并说明它是否在服务器端唯一……如果不是,将显示验证消息。除此之外,不管怎样,您将希望验证当你要保存电子邮件时,请再次删除它。web的性质是无状态的,每个请求都必须单独验证。这篇文章确实帮助了我。我遇到了完全相同的问题,但我必须对代码进行一些修改。一个限制必须是“A”而不是“E”,scope.apply()抛出了一个异常,说“$digest已在进行中”。因此,我在成功回调中内联了ctrl.setValidity()调用,效果非常好。这非常有帮助!我必须做一个更改:最新版本没有angular.forEach,因此我将其更新为使用$。each:I
<script type="text/javascript" src="../your/path/remoteValidate.js"></script>
var app = angular.module( 'myApp', [ 'remoteValidate' ] );
<input type="text" name="login"
ng-model="user.login"
remote-validate="( '/ajax/validation/login', ['not_empty',['min_length',2],['max_length',32],'domain','unique'] )"
required
/>
<br/>
<div class="form-input-valid" ng-show="form.login.$pristine || (form.login.$dirty && rv.login.$valid)">
From 2 to 16 characters (numbers, letters and hyphens)
</div>
<span class="form-input-valid error" ng-show="form.login.$error.remoteValidate">
<span ng:bind="form.login.$message"></span>
</span>
public function action_validation(){
$field = $this->request->param('field');
$value = Arr::get($_POST,'value');
$rules = Arr::get($_POST,'rules',[]);
$aValid[$field] = $value;
$validation = Validation::factory($aValid);
foreach( $rules AS $rule ){
if( in_array($rule,['unique']) ){
/// Clients - Users Models
$validation = $validation->rule($field,$rule,[':field',':value','Clients']);
}
elseif( is_array($rule) ){ /// min_length, max_length
$validation = $validation->rule($field,$rule[0],[':value',$rule[1]]);
}
else{
$validation = $validation->rule($field,$rule);
}
}
$c = false;
try{
$c = $validation->check();
}
catch( Exception $e ){
$err = $e->getMessage();
Response::jEcho($err);
}
if( $c ){
$response = [
'isValid' => TRUE,
'message' => 'GOOD'
];
}
else{
$e = $validation->errors('validation');
$response = [
'isValid' => FALSE,
'message' => $e[$field]
];
}
Response::jEcho($response);
}