Flutter规则验证插件drules的使用

Flutter规则验证插件drules的使用

Drules 是一个用于 Dart 的简单规则引擎。它允许你以 JSON 格式定义规则,并在给定的上下文中执行这些规则。规则以简单的 JSON 格式定义,可以轻松扩展以支持更复杂的规则。

使用

要将 Drules 用作 Dart 项目中的依赖项,请添加以下内容到你的 pubspec.yaml 文件中:

dart pub add drules

简单使用示例

以下是一个简单的使用示例:

import 'package:drules/drules.dart';

void main() async {
  var jsonRules = [
    '''
    {
        "name": "rule1",
        "conditions": {
          "operator": ">",
          "operands": ["age", 18]
        },
        "actionInfo": {
            "onSuccess": {
                "operation": "print",
                "parameters": ["You are an adult"]
            }
        }
    }
    ''',
    '''
    {
        "name": "rule2",
        "conditions": {
          "operator": "<",
          "operands": ["age", 18]
        },
        "actionInfo": {
            "onSuccess": {
                "operation": "print",
                "parameters": ["You are a child as your age is ${age}"]
            }
        }
    }
    ''' 
  ];

  var ruleRepository = StringRuleRepository(jsonRules);
  var ruleEngine = RuleEngine(ruleRepository);

  var context = RuleContext();
  context.addFact("age", 20);

  await ruleEngine.run(context);
}

特性

  • 规则以简单的 JSON 格式定义。
  • 支持基本条件和操作。
  • 可以轻松扩展以支持更复杂的规则。
  • 支持异步操作。
  • 支持自定义操作。
  • 支持自定义条件。

规则

规则定义在简单的 JSON 格式中。一个规则包含以下字段:

  • id: 规则的唯一标识符。如果没有提供,会自动生成。
  • name: 规则的名称。这是可选的,可用于调试目的。
  • priority: 规则的优先级。规则按优先级顺序执行,默认优先级为 0。
  • enabled: 一个标志,指示规则是否启用。默认值为 true。
  • conditions: 需要满足的条件以执行该规则。更多关于条件的细节见下文。
  • actionInfo: 当规则激活时要执行的操作信息。actionInfo 定义如下:
    • onSuccess: 规则成功时要执行的操作。
      • operation: 要执行的操作。
      • parameters: 传递给操作的参数。
    • onFailure: 因错误导致规则执行失败时要执行的操作。
      • operation: 要执行的操作。
      • parameters: 传递给操作的参数。

条件

条件由以下字段组成:

  • operator: 用于评估条件的操作符。它可以是以下内置操作符之一或任何用户定义的操作符:
    • ==: 等于
    • !=: 不等于
    • >: 大于
    • <: 小于
    • >=: 大于等于
    • <=: 小于等于
    • !: 对操作数取反
    • all: 所有操作数必须为真
    • any: 任一操作数必须为真
    • none: 所有操作数必须为假
    • contains: 第一个操作数必须包含第二个操作数
    • startsWith: 第一个操作数必须以第二个操作数开头
    • endsWith: 第一个操作数必须以第二个操作数结尾
    • matches: 第一个操作数必须匹配第二个操作数中的正则表达式
    • expression: 第一个操作数必须使用第二个操作数中的表达式求值为真
  • operands: 用于评估的运算对象列表。

示例

简单条件

{
    "operator": ">",
    "operands": ["age", 18]
}

复杂条件

{
    "operator": "all",
    "operands": [
        {
            "operator": ">",
            "operands": ["age", 18]
        },
        {
            "operator": "<",
            "operands": ["age", 60]
        }
    ]
}

表达式条件

Drules 支持表达式条件。表达式条件允许你定义自定义表达式来评估条件。它使用 template_expressions 包来评估表达式。

如果要在表达式中使用 Dart 对象,你必须将 MemberAccessor 对象传递给 RuleContext 对象。MemberAccessor 对象提供了对表达式中 Dart 对象的字段/方法的访问。

// 用户定义的对象
class Counter {
  int _value;

  Counter(this._value);

  void increment() {
    _value++;
  }

  int get value => _value;
}

var context = RuleContext(resolve: [
    MemberAccessor<Counter>({
        'value': (c) => c.value,
        'increment': (c) => c.increment,
    }),
]);
context.addFact('counter', Counter(2));

表达式条件定义如下:

{
    "operator": "expression",
    "operands": ["counter.value == 2"]
}

自定义条件

可以通过扩展 Condition 类来定义自定义条件。它必须在 RuleEngine 对象中注册才能在规则中使用。

ruleEngine.registerCondition(CustomCondition('isEven', (operands, context) {
    return operands[0] % 2 == 0;
}));

然后可以在规则中这样使用:

{
    "operator": "isEven",
    "operands": [2]
}

操作

操作由以下字段组成:

  • operation: 要执行的操作。操作可以是以下内置操作之一或任何用户定义的操作:
    • print: 将输出打印到控制台。
    • expression: 评估 Dart 表达式。
    • stop: 停止进一步执行规则或管道中的其他操作。
    • chain: 在链中定义的所有操作必须按定义的顺序执行。
    • parallel: 在并行块中定义的所有操作必须并行执行。
    • pipe: 一个操作的输出作为下一个操作的输入。
  • parameters: 传递给操作的参数。

示例

打印操作

{
    "operation": "print",
    "parameters": ["You are an adult"]
}

表达式操作

Drules 支持表达式操作。表达式操作允许你定义自定义表达式来评估操作。与表达式条件类似,你必须在 RuleContext 对象中设置 MemberAccessor 对象以在表达式中使用 Dart 对象。

{
    "operation": "expression",
    "parameters": ["counter.increment()"]
}

自定义操作

可以通过扩展 Action 类或使用 CustomAction 类来定义自定义操作。它必须在 RuleEngine 对象中注册才能在规则中使用。

ruleEngine.registerAction(CustomAction('log', (parameters, context) {
    print(parameters[0]);
}));

然后可以在规则中这样使用:

{
    "operation": "log",
    "parameters": ["You are an adult"]
}

规则上下文

RuleContext 对象用于存储事实和 MemberAccessor 对象。MemberAccessor 对象提供了对表达式中 Dart 对象的字段/方法的访问。

var context = RuleContext(resolve: [
    MemberAccessor<Counter>({
        'value': (c) => c.value,
        'increment': (c) => c.increment,
    }),
], facts: {
    'counter': Counter(2),
});

规则仓库

RuleRepository 对象用于存储规则。

StringRuleRepository

StringRuleRepositoryRuleRepository 接口的一个简单实现,它将规则存储在一个字符串列表中。

var jsonRules = [
    '''
    {
        "name": "rule1",
        "conditions": {
            "operator": ">",
            "operands": ["age", 18]
        },
        "actionInfo": {
            "onSuccess": {
                "operation": "print",
                "parameters": ["You are an adult"]
            }
        }
    }
    '''
];

var ruleRepository = StringRuleRepository(jsonRules);

FileRuleRepository

FileRuleRepositoryRuleRepository 接口的一个实现,它从文件或目录中读取规则。

var ruleRepository = FileRuleRepository(
    fileNames: [
        'rules/rule_one.json',
        'rules/rule_two.json',
    ],
);

激活事件

Drules 支持激活事件。激活事件是一个触发规则执行的信号。激活事件包含有关被激活的规则、触发规则的事实和规则结果的信息。

要监听激活事件,你可以向 RuleEngine 对象添加一个监听器。

ruleEngine.addListener((event) {
    print(event);
});

或者你可以使用 + 操作符添加一个监听器。

ruleEngine + print;

更多关于Flutter规则验证插件drules的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter规则验证插件drules的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


drules 是一个用于 Flutter 的规则验证库,它允许你轻松地定义和应用验证规则来验证数据。这个库非常适合用于表单验证、对象验证等场景。以下是如何使用 drules 的基本步骤。

1. 添加依赖

首先,你需要在 pubspec.yaml 文件中添加 drules 依赖:

dependencies:
  flutter:
    sdk: flutter
  drules: ^1.0.0  # 请检查最新版本

然后运行 flutter pub get 来安装依赖。

2. 定义验证规则

你可以通过创建一个继承自 Rule 的类来定义验证规则。每个规则必须实现 validate 方法。

import 'package:drules/drules.dart';

class RequiredRule extends Rule<String> {
  @override
  ValidationError? validate(String? value) {
    if (value == null || value.isEmpty) {
      return ValidationError('This field is required.');
    }
    return null;
  }
}

class MinLengthRule extends Rule<String> {
  final int minLength;

  MinLengthRule(this.minLength);

  @override
  ValidationError? validate(String? value) {
    if (value != null && value.length < minLength) {
      return ValidationError('Minimum length is $minLength.');
    }
    return null;
  }
}

3. 使用验证器

你可以在你的数据模型或表单中使用这些规则进行验证。

class User {
  String? name;

  User({this.name});

  Map<String, ValidationError?> validate() {
    return {
      'name': Validator<String>([RequiredRule(), MinLengthRule(3)]).validate(name),
    };
  }
}

4. 处理验证错误

在你的 UI 中,你可以调用 validate 方法并处理返回的验证错误。

class UserForm extends StatefulWidget {
  @override
  _UserFormState createState() => _UserFormState();
}

class _UserFormState extends State<UserForm> {
  final User user = User();
  Map<String, ValidationError?> errors = {};

  void _validate() {
    setState(() {
      errors = user.validate();
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('User Form')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          children: [
            TextField(
              onChanged: (value) {
                user.name = value;
              },
              decoration: InputDecoration(
                labelText: 'Name',
                errorText: errors['name']?.message,
              ),
            ),
            SizedBox(height: 20),
            ElevatedButton(
              onPressed: _validate,
              child: Text('Validate'),
            ),
          ],
        ),
      ),
    );
  }
}

5. 自定义错误消息

你可以在 ValidationError 中自定义错误消息,或者在规则类中直接返回错误消息。

class ValidationError {
  final String message;

  ValidationError(this.message);
}
回到顶部