如何在 Camunda 中处理可变数量的过程变量
How to handle variable number of process variables in Camunda
我是 Camunda 的新手,没有找到任何解释如何实现以下目标的教程或参考资料:
在启动流程时,我希望用户在发票中添加任意数量的项目。在下一个用户任务中,所有这些项目及其数量都应该打印给批准数据的人。
我还不明白如何使进程及其变量之间的这种 1:n 关系发挥作用。我需要为每个项目启动子流程吗?还是我必须使用自定义 Java 对象?如果是这样,我如何才能将表单元素映射到任务列表中的此类对象?
我在 Thorben 提供的链接的帮助下开始工作。
诀窍是使用 JSON 流程变量来存储更复杂的数据结构。我在 "Start Event" 中初始化了这样的列表。这可以在表单中完成,也可以在我的例子中在 Listener 中完成:
execution.setVariable("items", Variables.objectValue(Arrays.asList(dummyItem)).serializationDataFormat("application/json").create());
请注意,我添加了一个 dummyItem,因为空列表在序列化期间会丢失其类型信息。
接下来在我的自定义表单中我加载此列表并且可以 add/remove 项目。使用 camForm 回调可以保留列表。
<form role="form" name="form">
<script cam-script type="text/form-script">
/*<![CDATA[*/
$scope.items = [];
$scope.addItem = function() {
$scope.items.push({name: '', count: 0, price: 0.0});
};
$scope.removeItem = function(index) {
$scope.items.splice(index, 1);
};
camForm.on('form-loaded', function() {
camForm.variableManager.fetchVariable('items');
});
// variables-fetched is not working with "saved" forms, so we need to use variables-restored, which gets called after variables-fetched
camForm.on('variables-restored', function() {
$scope.items = camForm.variableManager.variableValue('items');
});
camForm.on('store', function() {
camForm.variableManager.variableValue('items', $scope.items);
});
/*]]>*/
</script>
<table class="table">
<thead>
<tr><th>Name</th><th>Count</th><th>Price</th><th></th></tr>
</thead>
<tbody>
<tr ng-repeat="i in items">
<td><input type="text" ng-model="i.name"/></td>
<td><input type="number" ng-model="i.count"/></td>
<td><input type="number" ng-model="i.price"/></td>
<td>
<button class="btn btn-default" ng-click="removeItem($index)">
<span class="glyphicon glyphicon-minus"></span>
</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<button class="btn btn-default" ng-click="addItem()">
<span class="glyphicon glyphicon-plus"></span>
</button>
</td>
</tr>
</tfoot>
</table>
</form>
有两件事还没有奏效:
- 字段验证,例如对于数字字段
- 当 adding/removing 行
时,"save" 按钮上使用的脏标志不会更新
我是 Camunda 的新手,没有找到任何解释如何实现以下目标的教程或参考资料:
在启动流程时,我希望用户在发票中添加任意数量的项目。在下一个用户任务中,所有这些项目及其数量都应该打印给批准数据的人。
我还不明白如何使进程及其变量之间的这种 1:n 关系发挥作用。我需要为每个项目启动子流程吗?还是我必须使用自定义 Java 对象?如果是这样,我如何才能将表单元素映射到任务列表中的此类对象?
我在 Thorben 提供的链接的帮助下开始工作。
诀窍是使用 JSON 流程变量来存储更复杂的数据结构。我在 "Start Event" 中初始化了这样的列表。这可以在表单中完成,也可以在我的例子中在 Listener 中完成:
execution.setVariable("items", Variables.objectValue(Arrays.asList(dummyItem)).serializationDataFormat("application/json").create());
请注意,我添加了一个 dummyItem,因为空列表在序列化期间会丢失其类型信息。
接下来在我的自定义表单中我加载此列表并且可以 add/remove 项目。使用 camForm 回调可以保留列表。
<form role="form" name="form">
<script cam-script type="text/form-script">
/*<![CDATA[*/
$scope.items = [];
$scope.addItem = function() {
$scope.items.push({name: '', count: 0, price: 0.0});
};
$scope.removeItem = function(index) {
$scope.items.splice(index, 1);
};
camForm.on('form-loaded', function() {
camForm.variableManager.fetchVariable('items');
});
// variables-fetched is not working with "saved" forms, so we need to use variables-restored, which gets called after variables-fetched
camForm.on('variables-restored', function() {
$scope.items = camForm.variableManager.variableValue('items');
});
camForm.on('store', function() {
camForm.variableManager.variableValue('items', $scope.items);
});
/*]]>*/
</script>
<table class="table">
<thead>
<tr><th>Name</th><th>Count</th><th>Price</th><th></th></tr>
</thead>
<tbody>
<tr ng-repeat="i in items">
<td><input type="text" ng-model="i.name"/></td>
<td><input type="number" ng-model="i.count"/></td>
<td><input type="number" ng-model="i.price"/></td>
<td>
<button class="btn btn-default" ng-click="removeItem($index)">
<span class="glyphicon glyphicon-minus"></span>
</button>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td colspan="4">
<button class="btn btn-default" ng-click="addItem()">
<span class="glyphicon glyphicon-plus"></span>
</button>
</td>
</tr>
</tfoot>
</table>
</form>
有两件事还没有奏效:
- 字段验证,例如对于数字字段
- 当 adding/removing 行 时,"save" 按钮上使用的脏标志不会更新