【问题标题】:AngularJS + custom validationsAngularJS + 自定义验证
【发布时间】:2013-06-20 10:34:24
【问题描述】:

根据我自己阅读和检查的内容,我对 AngularJS + 自定义验证有一些疑问:

  • AngularJS 为简单的字段验证(ng-require,...)提供了很好的帮助。
  • 实现单字段自定义验证的最佳方式是通过指令(不会污染控制器)。

当我们有影响多个文件的自定义业务验证时,我会产生疑问。让我们检查以下简单场景:

  • 我们正在编辑航班到达状态,字段:状态(着陆/预定/延误)、cmets(关于航班状态的其他信息)。
  • 我要应用的业务验证是:仅当状态字段值为“延迟”时才需要 cmets 字段。

    我实现它的方式:

  • 定义一个指令来处理 Status + Comments 字段的变化(状态通过 $watch)。
  • 该指令将业务验证委托给服务

    我认为这种方法给我的好处是:

  • 我的业务服务验证被隔离。

  • 我可以轻松地将单元测试添加到该业务验证中。

  • 我可以重复使用它,它不依赖于 UI 元素。

    我已经在 J​​SFiddle (JSFiddle validation sample) 中编译了这个示例。

JS:


function MyCtrl($scope) {    
    $scope.arrival = {
        "id": 1,
        "originAirport": "Malaga (AGP)",
        "flightNumber": "Iberia 132",
        "dueAt": "2013-05-26T12:10:10",
        "status": 2,
        "info": "test"
    }
}


myApp.directive('validateinfofield', ['formArrivalValidation', function (formArrivalValidation) {
    return {
        require: "ngModel",
        link: function(scope, elm, attrs, ctrl) {


            ctrl.$parsers.unshift(function(viewValue){
                // Empty? Let's check status
                //if (!viewValue.length && scope.arrival.status == 3) {
                if(formArrivalValidation.validateInfoField(scope.arrival.status, viewValue)) {
                    ctrl.$setValidity('validInfo', true);
                } else {
                    ctrl.$setValidity('validInfo', false);
                }
            });

            // Let's add a watch to arrival.status if the values change we need to 
            // reevaluate, if comments is empty and status is delayes display error
            scope.$watch('arrival.status', function (newValue, oldValue) {
                if (formArrivalValidation.validateInfoField(newValue, scope.editArrivalForm.txInfo.$viewValue)) {
                    ctrl.$setValidity('validInfo', true);
                } else {
                    ctrl.$setValidity('validInfo', false);
                }
            });

        }
    };
}]);

// Validation Service, limited to our "business language"
myApp.factory('formArrivalValidation',

   function () {
       return {
           validateInfoField: function (status, infoField) {
               var isOk = true;

               if (status == 3) {
                   if (infoField == undefined) {
                       isOk = false;
                   } else {
                       if (!infoField.length)
                           isOk = false;
                   }
               }

               return isOk;
           },

       };
   });

这是一个很好的方法吗?有没有更好更简单的方法来实现这一点?

【问题讨论】:

标签: validation service angularjs directive


【解决方案1】:

关于这部分 - “我要应用的业务验证是:只有当状态字段值为“延迟”时才需要 cmets 字段。 对于评论字段设置 ng-required="flight.status == 'DELAYED'"

【讨论】:

  • 嘿!非常聪明的解决方案。我在这里担心的是它属于 UI 层,我们不能轻易添加自动化单元测试(例如,一些代码更改,我们的单元测试电池没有检测到 UI 上的更改)另一方面你得到解决方案不到一行代码,相当聪明。
  • 添加到这个。您可以将验证放在控制器上的方法中,然后对控制器进行单元测试....这应该是公认的答案。
【解决方案2】:

回到这个问题...一种有效的方法可能是编写一个接受第二个值作为参数的指令(例如 cmets 为空)

【讨论】:

    猜你喜欢
    • 2017-05-26
    • 2014-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多