AngularJS和可重用的强制字段验证规则

时间:2015-09-08 10:56:45

标签: angularjs spring architecture workflow rule-engine

我必须设计一个经典的,基于表单的操作Web应用程序。

每个表单都包含一些控件,主要是输入控件。其中许多控件都有验证或行为规则,有些规则仅对单个控件有效(jndependent checks),有些则依赖于其他控件(依赖检查)的值。

此外,某些控件在不同的表单中具有相同的语义含义。

例如,“客户名称”输入字段的最大长度应始终为50个字符,并且在许多不同的表单之间共享。另一个例子是基于年龄字段过滤“文档”组合框(即:具有少于18年的客户具有不同的文档)。如果该组合中没有文档,那么它应该完全消失。

规则应该集中并重复使用。即使我可以在控制器中包含的函数中定义规则,我也不希望程序员记住为某个字段添加验证规则,因为我确信他不会

我所追求的是一种基于AngularJS的智能方法,用于为所有表单的字段定义可重用规则,以及一种强制程序员在字段中自动使用这些规则的方法。理想情况下,规则应该在服务器上定义并在需要时下载,因为出于明显的安全原因,我必须在服务器端重做检查。

我看过角度自定义指令,但我不确定这是实现这种事情的正确方法。它肯定有效,但我想知道如何定义跨字段规则并强制使用它们。

例如,使用自定义指令myCustomerName作为客户字段名称:

app.js     var myApp = angular.module(“MyApp”,[]);

myApp.directive("myCustomerName", 
    function() 
    {
        return 
        {
            restrict: 'E',
            templateUrl: 'customer_name.html' 
        };
    }
);

customer_name.html

<div class="form-group">
    <label for="customerName">Customer Name</label>
    <input type="text" class="form-control" id="customerName" ng-model="customerName">
</div>

等。但后来我没有交叉检查规则!

我可以改为定义一个更通用的自定义指令:

myApp.directive("ufeCheck", 
    function() 
    {
        return { 
            restrict: 'E',
            templateUrl: function(e, attr) { 
                return attr.type + '.html';
            }
        };
    }
);

然后在html中使用它,如:

<ufe_check type="customer_name"></ufe_check>
<ufe_check type="customer_age"></ufe_check>

但是, 我在哪里进行交叉检查? 我该如何下载服务器定义的规则?

我认为我需要规则引擎执行程序,客户端和AngularJS表单验证兼容。

我看过Valdr:https://github.com/netceteragroup/valdr 它很好,但规则只在客户端定义,而不是跨领域。

2 个答案:

答案 0 :(得分:0)

这是非常常见的问题,我不确定是否有货架产品可以解决您的所有问题。首先:您不能只在后端和前端重用验证代码,因为它们是两个相似但不同的验证。例如,在其余的api中不需要'重复密码'字段。另一个例子:不应在前端验证验证码。

交叉场验证很容易。你仍然可以封装在一个指令/组件中,它接受字段引用/名称作为输入,然后使用angular的on-change来验证逻辑。

在服务器上我不会存储规则/ dsl,我只是重用前端的js代码并在后端(节点或其他js运行时)上运行该代码。如果您使用自己的dsl,则始终存在dsl不支持的情况。规则可能非常复杂,因此更容易使用完整的编程语言,而不是人工即时创建的dsl。

然而我不知道如何“强制”程序员使用它。简单地使用“required”标记添加新字段总是更容易,而不是在代码库或文档中搜索类似于他需要的内容。我能想到的一种方法是让一些测试/代码分析器断言在某些文件夹中绝对没有自定义验证,并且每个字段都附加了一个自定义验证器/标记。但我不确定这对所有其他开发者来说是否方便

答案 1 :(得分:0)

您可以在角度上创建策略以将调用发送到后端以验证数据。这种方法的最大优点是在一个地方集中验证。我甚至不会理解保持一个地方规则和验证的优点。例如,您可以在后端使用ValidateData类。

有一个带有角度的api可以做到这一点。 https://github.com/webadvanced/ng-remote-validate。用法很简单,看看:

<!-- This defined input for validation with context for this ng-remote-validate-->
<input type="password" 
       name="currentPassword" 
       placeholder="Current password" 
       ng-model="password.current" 
       ng-remote-validate="/customer/validpassword"
       ng-remote-throttle="550"
       ng-remote-method="GET"
       required>

<!-- This defined input for validation with context for this ng-remote-validate-->
<input type="text" 
       name="email" 
       placeholder="Email address" 
       ng-model="email" 
       ng-remote-validate="[ '/customer/email-registered', '/customer/email-restricted' ]"
       ng-remote-throttle="800"
       ng-remote-method="POST"
       required>

<!-- This wait validation -->
<span class="message" ng-show="myForm.inputName.$pending">validating...</span>

<!-- This submit form an run validation -->
<button type="submit" ng-disabled="myForm.$invalid || myForm.$pending" ng-click="...">Go!</button>