AngularJs表单验证时间指令

发布于 2022-09-04 03:05:17 字数 3809 浏览 10 评论 0

我想写一个指令用来校验结束时间在开始时间之后的指令


angular.module('MyApp')
    .directive('dateAfter',function($timeout){
        return{
            require: "ngModel",
            priority:1,
            link:function (scope, element, attrs, ngModel) {
                if(!ngModel) {
                    throw new Error("dateAfter can't find ng-model directive");
                }

                scope.attrs = attrs;
                //ngModel.$pending['dateAfter'] = true;
                //ngModel.$error.dateAfter = true;
                scope.$watch('attrs.dateAfter',function(newValue,oldValue,scope){
                    if(newValue){
                        var value = angular.copy(ngModel.$viewValue);
                        ngModel.$setViewValue("");
                        ngModel.$setViewValue(value);
                        //console.log('run validate');
                        //customValidator(ngModel.$modelValue);
                    }
                })

                function formatDate(value){
                    if((typeof(value) == "object") || (typeof(value) == "string")){
                        if(moment(value).isValid){
                            return value;
                        }
                    }
                    return undefined;
                }

                function compareDate(d1,d2){
                    //console.log(d1,d2);
                    return moment(d1).isSame(d2) || moment(d1).isAfter(d2);
                }

                //判断是否为undefined;
                function checkValue(value,msg){
                    if(typeof value == "undefined"){
                        throw new Error(msg);
                    }
                }

                //用于表单值本身变化时做校验
                var customValidator = function (value) {
                    //console.log('customValidator',ngModel);
                    if(!value){
                        ngModel.$setValidity("dateAfter", false);
                        return;
                    }

                    //如果attrs.dateAfter没有计算出来的时候,直接返回value
                    if(attrs.dateAfter == ""){
                        return value;
                    }
                    //获得待比较的值
                    var cmpDate = formatDate(attrs.dateAfter);
                    //获取model的值
                    var valueDate = formatDate(value);
                    //如果model的值有问题
                    checkValue(valueDate,'model有问题');
                    //如果待比较的值有问题。
                    checkValue(cmpDate,'dateAfter有问题');
                    //验证值的是否在待比较日期之后
                    var validity = ngModel.$isEmpty(value) || (compareDate(valueDate,cmpDate));
                    //设置验证结果
                    console.debug('validity,$error,$pending',validity,ngModel.$error,ngModel.$pending);
                    ngModel.$setValidity("dateAfter", validity);
                    return validity?value:undefined;
                };

                //Model的数据转换为View交互控件显示的值
                ngModel.$formatters.push(customValidator);
                //将交互控件得到的View值转换为Model数据
                ngModel.$parsers.push(customValidator);

            }
        }
    })

使用时候在html中加入,此处我用的日历组件,日期格式遵循YYYY-MM-DD。

<form name="myForm">
<input name="stTime" type="text" ng-model="startTime" />
<input name="lvTime" type="text" date-after="{{startTime}}" ng-model="endTime" />
</form>

以上代码是可以运行。

但是当我在$watch中直接执行customValidator(ngModel.$modelValue)时,
修改开始时间到结束时间之后,并不会响应如下提示。
而是需要通过改变model的值让它自己做校验才能响应。

<div ng-show="myForm.lvTime.$error.dateAfter">
    结束时间应在开始时间之后
</div>

虽然问题是解决了。总感觉强行修改一波model值,
让它做校验这种解决方法不太好。
问下各位大神有没有更好的方法

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

你怎么这么可爱啊 2022-09-11 03:05:17
后来自己又写了一个dateBefore的指令,跟这个指令类似。两个指令都不需要$watch那个其他的变量。
提示语改成了
dateBeforeError ->  XXX应在XXX之前  
dateAfterError - >  XXX应在XXX之后。

上个代码供参考。


.directive('dateBefore',function(){
        return{
            require: "ngModel",
            link:function (scope, element, attrs, ngModel) {
                if(!ngModel) {
                    throw new error("beforeToday can't find ng-model directive");
                }

                function formatDate(value){
                    if((typeof(value) == "object") || (typeof(value) == "string")){
                        if(moment(value).isValid){
                            return value;
                        }
                    }
                    return undefined;
                }

                function compareDate(d1,d2){
                    return moment(d1).isSame(d2) || moment(d1).isBefore(d2);
                }

                //判断是否为undefined;
                function checkValue(value,msg){
                    if(typeof value == "undefined"){
                        throw new Error(msg);
                    }
                }

                var customValidator = function (value) {
                    if(!value){
                        ngModel.$setValidity("dateAfter", false);
                        return;
                    }

                    //如果attrs.dateAfter没有计算出来的时候,直接返回value
                    if(attrs.dateBefore == ""){
                        return value;
                    }

                    //获得待比较的值
                    var cmpDate = formatDate(attrs.dateBefore);
                    //获取model的值
                    var valueDate = formatDate(value);
                    //如果model的值有问题
                    checkValue(valueDate,'model有问题');
                    //如果待比较的值有问题。
                    checkValue(cmpDate,'dateBefore有问题');
                    //验证值的是否在待比较日期之前
                    var validity = ngModel.$isEmpty(value) || (compareDate(valueDate,cmpDate));
                    ngModel.$setValidity("dateBefore", validity);
                    return validity ? value : undefined;
                };
                ngModel.$formatters.push(customValidator);
                ngModel.$parsers.push(customValidator);
            }
        }
    })

.directive('dateAfter',function($timeout){
        return{
            require: "ngModel",
            priority:1,
            link:function (scope, element, attrs, ngModel) {
                if(!ngModel) {
                    throw new Error("dateAfter can't find ng-model directive");
                }


                function formatDate(value){
                    if((typeof(value) == "object") || (typeof(value) == "string")){
                        if(moment(value).isValid){
                            return value;
                        }
                    }
                    return undefined;
                }

                function compareDate(d1,d2){
                    //console.log(d1,d2);
                    return moment(d1).isSame(d2) || moment(d1).isAfter(d2);
                }

                //判断是否为undefined;
                function checkValue(value,msg){
                    if(typeof value == "undefined"){
                        throw new Error(msg);
                    }
                }

                //用于表单值本身变化时做校验
                var customValidator = function (value) {
                    //console.log('customValidator',ngModel);
                    if(!value){
                        ngModel.$setValidity("dateAfter", false);
                        return;
                    }

                    //如果attrs.dateAfter没有计算出来的时候,直接返回value
                    if(attrs.dateAfter == ""){
                        return value;
                    }
                    //获得待比较的值
                    var cmpDate = formatDate(attrs.dateAfter);
                    //获取model的值
                    var valueDate = formatDate(value);
                    //如果model的值有问题
                    checkValue(valueDate,'model有问题');
                    //如果待比较的值有问题。
                    checkValue(cmpDate,'dateAfter有问题');
                    //验证值的是否在待比较日期之后
                    var validity = ngModel.$isEmpty(value) || (compareDate(valueDate,cmpDate));
                    //设置验证结果
                    ngModel.$setValidity("dateAfter", validity);
                    return validity?value:undefined;
                };

                //Model的数据转换为View交互控件显示的值
                ngModel.$formatters.push(customValidator);
                //将交互控件得到的View值转换为Model数据
                ngModel.$parsers.push(customValidator);

                
            }
        }
    })

<form name="myForm">
    <input name="stTime"  type="text" date-before="{{levTime}}"  ng-model="startTime"/>
    <input name="levTime" type="text" date-after="{{startTime}}" ng-model="endTime"/>
</form>


<b ng-show='myForm.stTime.$error.dateBefore == true'>开始时间请选择在结束时间之前</b>
<b ng-show='myForm.levTime.$error.dateAfter == true'>结束时间请选择在开始时间之后</b>

因为代码没贴全。需要的可以根据这个修改。。。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文