使用 $http 的 AngularJS 自定义表单验证 [英] AngularJS custom form validation using $http

查看:22
本文介绍了使用 $http 的 AngularJS 自定义表单验证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个看起来像这样的表单:

<input type="hidden" value="{{item.CloneUrl}}" name="cloneurl"/><input type="hidden" value="{{Username}}" name="username"/><input type="radio" name="deploymenttype" ng-model="item.deploymentType" value="azure" checked="checked">Azure<br/><input type="radio" name="deploymenttype" ng-model="item.deploymentType" value="ftp">FTP<div id="azure" ng-show="item.deploymentType=='azure'"><label for="azurerepo">Azure Git Repo</label><input type="text" name="azurerepo" ng-model="item.azurerepo" ng-class="{error: myForm.azurerepo.$invalid}" ng-required="item.deploymentType=='azure'"/>

<div id="ftp" ng-show="item.deploymentType=='ftp'"><label for="ftpserver">FTP 服务器</label><input type="text" name="ftpserver" ng-model="item.ftpserver" ng-class="{error: myForm.ftpserver.$invalid}" ng-required="item.deploymentType=='ftp'"/><label for="ftppath">FTP 路径</label><input type="text" name="ftppath" ng-model="item.ftppath" ng-class="{error: myForm.ftppath.$invalid}" ng-required="item.deploymentType=='ftp'"/><label for="ftpusername">FTP 用户名</label><input type="text" name="ftpusername" ng-model="item.ftpusername" ng-class="{error: myForm.ftpusername.$invalid}" ng-required="item.deploymentType=='ftp'"/><label for="ftppassword">FTP 密码</label><input type="password" name="ftppassword" ng-model="item.ftppassword" ng-class="{error: myForm.ftppassword.$invalid}" ng-required="item.deploymentType=='ftp'"/>

<input type="submit" value="Save" ng-disabled="myForm.$invalid"/></表单>

它的设置使得一旦输入数据,必填字段和保存按钮都可以工作.但是,我的部分验证将是,用户是否已经注册?" 我将使用输入的数据通过 $http 通过 POST 访问服务器.

我应该将该逻辑放在 saveDeployment() 函数中还是有更好的地方放置它?

*更新:*

我已经实现了下面的内容,它作为一个元素的属性应用,但它在我不喜欢的每次按键时调用服务器/数据库:

 app.directive('repoAvailable', function ($http, $timeout) {//可用返回 {要求:'ngModel',链接:函数(范围,元素,属性,ctrl){控制台日志(ctrl);ctrl.$parsers.push(function (viewValue) {//这里设置为true,否则不会//当之前的验证器失败时清除.ctrl.$setValidity('repoAvailable', true);如果(ctrl.$valid){//在这里设置为false,因为如果我们需要检查//电子邮件的有效性,直到//AJAX 响应.ctrl.$setValidity('checkingRepo', false);//现在做你的事,鸡翅.if (viewValue !== "" && typeof viewValue !== "undefined") {$http.post('http://localhost:12008/alreadyregistered',viewValue)//设置为'Test.json'使其返回true..success(功能(数据,状态,标题,配置){ctrl.$setValidity('repoAvailable', true);ctrl.$setValidity('checkingRepo', true);}).error(function (data, status, headers, config) {ctrl.$setValidity('repoAvailable', false);ctrl.$setValidity('checkingRepo', true);});} 别的 {ctrl.$setValidity('repoAvailable', false);ctrl.$setValidity('checkingRepo', true);}}返回视图值;});}};});

解决方案

你不需要在指令中发出 $http 请求,更好的地方是控制器.

您可以在控制器中指定方法 - $scope.saveDeployment = function () {//在这里您可以根据请求制作和处理您的错误 ... }; 您将错误保存到范围和然后创建一个指令来监视 $scope.yourResponseObject 并根据它设置有效性.

此外,如果您需要类似请求和输入字段模糊的错误,您需要使用 elem.bind('blur', ...) 创建一个简单的指令,您可以在其中调用 $scope.saveDeployment 带有处理有效性的回调.

看看例子,可能有类似的东西 - https://github.com/angular/angular.js/wiki/JsFiddle-Examples

I have a form that looks like this:

<form name="myForm" ng-submit="saveDeployment()">
    <input type="hidden" value="{{item.CloneUrl}}" name="cloneurl" />
    <input type="hidden" value="{{Username}}" name="username" />

    <input type="radio" name="deploymenttype" ng-model="item.deploymentType" value="azure" checked="checked">Azure 
    <br />
    <input type="radio" name="deploymenttype" ng-model="item.deploymentType" value="ftp">FTP

    <div id="azure" ng-show="item.deploymentType=='azure'">
        <label for="azurerepo">Azure Git Repo</label>
        <input type="text" name="azurerepo" ng-model="item.azurerepo" ng-class="{error: myForm.azurerepo.$invalid}" ng-required="item.deploymentType=='azure'" />
    </div>

    <div id="ftp" ng-show="item.deploymentType=='ftp'">
        <label for="ftpserver">FTP Server</label>
        <input type="text" name="ftpserver" ng-model="item.ftpserver" ng-class="{error: myForm.ftpserver.$invalid}" ng-required="item.deploymentType=='ftp'"  />

        <label for="ftppath">FTP Path</label>
        <input type="text" name="ftppath" ng-model="item.ftppath" ng-class="{error: myForm.ftppath.$invalid}" ng-required="item.deploymentType=='ftp'" />

        <label for="ftpusername">FTP Username</label>
        <input type="text" name="ftpusername" ng-model="item.ftpusername" ng-class="{error: myForm.ftpusername.$invalid}" ng-required="item.deploymentType=='ftp'"/>

        <label for="ftppassword">FTP Password</label>
        <input type="password" name="ftppassword" ng-model="item.ftppassword" ng-class="{error: myForm.ftppassword.$invalid}" ng-required="item.deploymentType=='ftp'"/>
    </div>

    <input type="submit" value="Save" ng-disabled="myForm.$invalid"/>

</form>

Its setup so that the required fields and Save button are all working once data is entered. However, part of my validation will be, "Is the user already registered?" where I will use the data entered to hit the server via POST using $http.

Should I put that logic in the saveDeployment() function or is there a better place to put it?

*UPDATE:*

I've implemented the below which is applied as an attribute on a element but it calls the server/database on every key press which I don't like:

 app.directive('repoAvailable', function ($http, $timeout) { // available
        return {
            require: 'ngModel',
            link: function (scope, elem, attr, ctrl) {
                console.log(ctrl);
                ctrl.$parsers.push(function (viewValue) {
                    // set it to true here, otherwise it will not 
                    // clear out when previous validators fail.
                    ctrl.$setValidity('repoAvailable', true);
                    if (ctrl.$valid) {
                        // set it to false here, because if we need to check 
                        // the validity of the email, it's invalid until the 
                        // AJAX responds.
                        ctrl.$setValidity('checkingRepo', false);

                        // now do your thing, chicken wing.
                        if (viewValue !== "" && typeof viewValue !== "undefined") {
                            $http.post('http://localhost:12008/alreadyregistered',viewValue) //set to 'Test.json' for it to return true.
                                .success(function (data, status, headers, config) {
                                    ctrl.$setValidity('repoAvailable', true);
                                    ctrl.$setValidity('checkingRepo', true);
                                })
                                .error(function (data, status, headers, config) {
                                    ctrl.$setValidity('repoAvailable', false);
                                    ctrl.$setValidity('checkingRepo', true);
                                });
                        } else {
                            ctrl.$setValidity('repoAvailable', false);
                            ctrl.$setValidity('checkingRepo', true);
                        }
                    }
                    return viewValue;
                });

            }
        };
    });

解决方案

You don't need to make $http request in directive, better place for it is controller.

You can specify method inside controller - $scope.saveDeployment = function () { // here you make and handle your error on request ... }; you'll save error to scope and then create a directive that will watch $scope.yourResponseObject and set validity based on it.

Also if you need something like request and error on input field blur instead, you need to create a simple directive with elem.bind('blur', ...) where you call $scope.saveDeployment with callback to handle validity.

Take a look on the examples, there might be something similar - https://github.com/angular/angular.js/wiki/JsFiddle-Examples

这篇关于使用 $http 的 AngularJS 自定义表单验证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
前端开发最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆