angularjs (Form)

Forms

为了让form以及控件、ngModel富有样式,可以增加以下class

通过在元素上添加repuired等验证指令  angularjs自动更具状态切换这些class

  • ng-valid (验证成功)

  • ng-invalid (验证失败)

  • ng-pristine(从未输入过)

  • ng-dirty(输入国)

angular中,表单是FormController的一个实例。表单实例可以随意地使用name属性暴露到scope中(只可意会,不可言传啊。。)

<!DOCTYPE HTML>
<html ng-app="ControlState">
<head>
    <meta charset="UTF-8">
    <title>ControlState</title>
    <style type="text/css">
        .ng-cloak {
            display: none;
        }
        .css-form input.ng-invalid.ng-dirty {
            background-color: #fa787e;
        }
        .css-form input.ng-valid.ng-dirty {
            background-color: #78fa89;
        }
    </style>
</head>
<body>
<div ng-controller="MyCtrl">
    <form novalidate name="formName">
        名字: <input ng-model="user.name" name="userName" type="text" required><br/>
        <div ng-show="formName.userName.$dirty&&formName.userName.$invalid">
            <span>请填写名字</span>
        </div>

        Email: <input ng-model="user.email" name="userEmail" type="email" required><br/>
        <div ng-show="formName.userEmail.$dirty && formName.userEmail.$invalid">提示:
            <span ng-show="formName.userEmail.$error.required">请填写Email</span>
            <span ng-show="formName.userEmail.$error.email">这不是一个有效的Email</span>
        </div>
        性别: <input value="男" ng-model="user.gender" type="radio">男
        <input value="女" ng-model="user.gender" type="radio">女
        <br/>
        <input type="checkbox" ng-model="user.agree" name="userAgree" required/>我同意:
        <input type="text" ng-show="user.agree" ng-model="user.agreeSign" required/>
        <br/>
        <div ng-show="!formName.userAgree || !user.agreeSign">请同意并签名~</div>
        <button ng-click="reset()" ng-disabled="isUnchanged(user)">RESET</button>
        <button ng-click="update(user)" ng-disabled="formName.$invalid || isUnchanged(user)">SAVE</button>
    </form>
    <pre>form = {{user | json}}</pre>
    <pre>saved = {{saved | json}}</pre>
</div>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">
    var app = angular.module("ControlState", []);
    app.controller("MyCtrl", function ($scope,$window) {
        $scope.saved = {};
        $scope.update = function(user) {
            $scope.saved = angular.copy(user);
        };

        $scope.reset = function() {
            $scope.user = angular.copy($scope.saved);
        };

        $scope.isUnchanged = function(user) {
            return angular.equals(user, $scope.saved);
        };

        $scope.reset();
    });
</script>
</body>
</html>

custrom Validation

  • Model到View更新   无论什么时候Model发生改变,所有的ngModelController.$formatters(model发生改变时触发数据有效验证和格式化转变)数组中的function将排队执行,所以在这里每一个function都有机会去格式化model的值,并且通过NgModelController.$setValidity修改空间的验证状态。

  • View到Model更新  无论任何时候用户与控件发生交互,将会触发NgModelCtroller.$setViewValue。这时候轮到执行NgModelController.$parsers(当控件从dom取值之后,将会执行这个数组中的所有方法,对值进行审查过滤或转换,也进行验证)数组中的所有方法。

在下面的例子中我们将创建两个directive

  • 第一个是integer,它负责验证输入到底是不是一个有效的整数。例如1.23是一个非法的值,因为它包含小数部分。注意,我们通过在数组头部插入(unshift)来代替在尾部插入(push),这因为我们想它首先执行并使用这个控件的值(估计这个Array是当作队列来使用的),我们需要在转换发生之前执行验证函数。

  • 第二个directivesmart-float。他将”1.2”和”1,2”转换为一个合法的浮点数”1.2”。注意,我们在这不可以使用HTML5input类型”number”,因为浏览器不允许用户输入我们预期的非法字符,如”1,2”(它只认识”1.2”)。

<!DOCTYPE HTML>
<html ng-app="CustomValidation">
<head>
    <meta charset="UTF-8">
    <title>CustomValidation</title>
    <style type="text/css">
        .ng-cloak {
            display: none;
        }
        .css-form input.ng-invalid.ng-dirty {
            background-color: #fa787e;
        }
        .css-form input.ng-valid.ng-dirty {
            background-color: #78fa89;
        }
    </style>
</head>
<body>
<div>
    <form novalidate name="formName">
        <div>
            大小(整数 0 - 10):<input integer type="number" ng-model="size" name="size" min="0" max="10"/>{{size}}{{formName.size.$error.integer}}<br/>

            <span ng-show="formName.size.$error.integer">这不是一个有效的整数</span>
            <span ng-show="formName.size.$error.min || formName.size.$error.max">
                数值必须在0到10之间
            </span>
        </div>
        <div>
            长度(浮点数):
            <input type="text" ng-model="length" name="length" smart-float/>
            {{length}}<br/>
            <span ng-show="formName.length.0error.float">这不是一个有效的浮点数</span>
        </div>
    </form>
</div>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">
    var app = angular.module("CustomValidation", []);
    var INTEGER_REGEXP = /^\-?\d*$/;
    app.directive("integer", function () {
        return {
            require:"ngModel",//NgModelController
            link:function(scope,ele,attrs,ctrl) {

                //View - >Model的更新
                ctrl.$parsers.unshift(function (viewValue) {
                
                //model -> view的更新吗??
                //console.log(viewValue, '++');
                    if(INTEGER_REGEXP.test(viewValue)) {  
                        ctrl.$setValidity("integer", true);
                        return viewValue;
                    }else {
                        ctrl.$setValidity("integer", false);
                        return undefined;
                    }
                });
            }
        };
    });
    var FLOAT_REGEXP = /^\-?\d+(?:[.]\d+)?$/;
    app.directive("smartFloat", function () {
        return {
            require:"ngModel",
            link:function(scope,ele,attrs,ctrl) {
                ctrl.$parsers.unshift(function(viewValue) {
                    if(FLOAT_REGEXP.test(viewValue)) {
                        ctrl.$setValidity("float", true);
                        return parseFloat(viewValue);
                    }else {
                        ctrl.$setValidity("float", false);
                        return undefined;
                    }
                });
            }
        }
    });
</script>
</body>
</html>

angular实现了所有HTML的基础控件(inputselecttextarea),能胜任大多数场景。然而,如果我们需要更加灵活,我们可以通过编写一个directive来实现自定义表单控件的目的。

  为了制定控件和ngModel一起工作,并且实现双向数据绑定,它需要:

  • 实现render方法,是负责在执行完并通过所有NgModelController.$formatters方法后,呈现数据的方法。

  • 调用$setViewValue方法,无论任何时候用户与控件发生交互,model需要进行响应的更新。这通常在DOM事件监听器里实现。

<!DOCTYPE HTML>
<html ng-app="CustomControl">
<head>
    <meta charset="UTF-8">
    <title>CustomControl</title>
    <style type="text/css">
        .ng-cloak {
            display: none;
        }
        div[contenteditable] {
            cursor: pointer;
            background-color: #D0D0D0;
        }
    </style>
</head>
<body ng-controller="MyCtrl">
<div>
    <div contenteditable="true" ng-model="content" title="点击后编辑">My Little Dada</div>
    <pre>model = {{content}}</pre>
    <button ng-click="reset()">reset model tirgger model to view($render)</button>
</div>
<script src="../angular-1.0.1.js" type="text/javascript"></script>
<script type="text/javascript">
    var app = angular.module("CustomControl", []);
    app.controller("MyCtrl", function ($scope) {
        $scope.reset = function() {
            $scope.content = "My Little Dada";
        };
    });
    app.directive("contenteditable", function () {
        return {
            require:"ngModel",
            link:function (scope, ele, attrs, ctrl) {
                //view -> model
                ele.bind("blur keyup",function() {
                    scope.$apply(function() {
                        console.log("setViewValue");
                        ctrl.$setViewValue(ele.text());
                    });
                });

                //model -> view
                ctrl.$render = function() {
                    //当根scope的model发生改变时 $render触发(00!)我这么认为
                    ele.html(scope.content);
                };
                //读取初始值
                ctrl.$setViewValue(ele.text());
            }
        };
    });
</script>
</body>
</html>


转载于:https://my.oschina.net/felumanman/blog/330624

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AngularJS是一个JavaScript框架,由Google开发和维护,用于构建动态Web应用程序。它是一个MVC(Model-View-Controller)框架,可以帮助开发人员更快地开发Web应用程序,同时提高应用程序的可维护性和可扩展性。 AngularJS通过指令(directive)和模板(template)来构建应用程序的用户界面。它提供了一组工具和服务,用于处理数据绑定(data binding)、依赖注入(dependency injection)、路由(routing)、表单验证(form validation)等任务。此外,AngularJS还提供了一些内置指令和服务,如ng-repeat、ng-model、$http、$scope等,使得开发人员可以更轻松地完成各种任务。 AngularJS的优点包括: 1. 数据绑定:AngularJS的数据绑定机制允许开发人员将数据模型和视图进行绑定,当数据模型发生变化时,视图也会自动更新。 2. 模块化:AngularJS使用模块化的设计,使得应用程序可以分解为多个小模块,易于管理和维护。 3. 依赖注入:AngularJS的依赖注入机制可以帮助开发人员更好地管理应用程序中的各种依赖关系,提高代码的可测试性和可重用性。 4. 双向数据绑定:AngularJS的双向数据绑定机制允许开发人员在视图中进行数据修改,同时也会更新数据模型。 5. 丰富的指令库:AngularJS提供了大量的指令和服务,使得开发人员可以更轻松地完成各种任务,如表单验证、路由、数据绑定等。 AngularJS的缺点包括: 1. 学习曲线:由于AngularJS采用了一些独特的概念和机制,因此需要花费一定的时间和精力来学习和理解。 2. 性能问题:由于AngularJS的数据绑定机制会对性能产生一定的影响,因此需要注意代码的优化和性能调优。 3. 兼容性问题:由于AngularJS是一个JavaScript框架,因此需要浏览器支持JavaScript才能正常运行,同时也需要考虑不同浏览器的兼容性问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值