AngularJS +自定义的验证

问题描述:

我对AngularJS +自定义验证有些疑惑,从我已阅读并检查通过自己:AngularJS +自定义的验证

  • AngularJS提供了简单的现场验证的伟大的帮手(NG-要求,...) 。
  • 实现单个字段自定义验证的最佳方式是通过指令(不污染控制器)。

当我们有定制的业务验证,影响到多个字段时,我的疑惑来了。让我们来看看下面这个简单的场景:

simple UI flight status

  • 我们正在编辑一个航班到达的状态,场:状态(登陆/计划/延迟),评论(ABOT飞行状态附加信息)。
  • 我想要应用的业务验证是:仅当状态字段值为“延迟”时才需要注释字段。

    我已经实现了它的方式:

Directive + Service

  • 定义指令(通过$观察状态)照顾的状态+评论领域的变化。
  • 该指令代表的业务验证为服务

    我觉得这种做法是给我的好处是:

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

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

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

    我已经在JSFiddle(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; 
      }, 

     }; 
    }); 

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

+0

[如何自定义验证添加到AngularJS形式? ](https://stackoverflow.com/q/12581439/6521116) –

关于此部分 - “我要应用的业务验证是:仅当状态字段值为”延迟“时,才需要注释字段 用于注释字段设置ng-required =”flight.status =='DELAYED “”

+0

嗨!非常聪明的解决方案,我的关注点在于它是UI层的东西,我们不能轻易添加自动化单元测试(例如一些代码发生变化,我们的单元测试电池没有检测到用户界面上的变化),另一方面,您使用不到一行代码就可以获得解决方案,这非常明智。 – Braulio

+0

添加到此。你可以把验证放在控制器的一个方法上,然后单元测试控制器....这应该是被接受的答案。 – dannypaz

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