Skip to main content

表单字段值变化,刷新另一个字段数据源

当我们需要在一个字段值变更时,让另一个字段的数据源发生变化。

业务场景​

我们在维护某个学院的班级信息时,我们要对班级设置专业,但是专业又和学院挂钩。当选择不同学院时,我们要让专业数据源选项动态切换(每个学院的专业是不同的),只能选择学院下开授的专业。

配置​

通过接口定义数据源,有以下三种方案:

方案一(适用于参数可穷举或通过条件组件可满足业务)​

通过条件组件,根据不同的条件分支选用不同的数据源。

适用于静态数据源,如果上述场景的院系是固定值(院系1、院系2),并且不会动态添加院系,我们可以明确地通过两个条件组件匹配这两个固定的院系值,这种方案配置较为简单直接。

条件设置​

通过不同字段的值进行条件组合匹配。

方案二(适用于单实体数据源,通过条件动态控制数据源参数)​

使用C#脚本组件,根据不同条件,直接拼接查询条件,不满足则不拼接。

适用于实体数据源,参数值不便于穷举,在上述场景中,真实情况是院系不可能只存在两个,而通常可以在一个地方维护院系数据,因此这是一个不便于穷举的值。我们需要通过某个参数决定是否拼接额外的查询条件来获取数据源数据。

C#脚本组件是较为强大的组件,可以完全覆盖几乎全部实体数据源使用场景,但由于需要使用脚本,对于脚本开发没有经验的人来说不是十分友好,上手较为困难。因此,如果方案一能满足,优先使用方案一。

C#组件脚本设置​

using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Chameleon.Common;
using Chameleon.Common.Context;
using Chameleon.Common.Exceptions;
using Chameleon.Common.Models;
using Chameleon.Database;

public class ChameleonCSharpScript
{
public object Execute(ComponentContext context, IChameleonDbContext dbContext, ILogger logger)
{
// 表单的字段值可以在请求体中获取到
var obj = context.Request?.List?.FirstOrDefault();

if (obj == null)
return "";

// 从参数中获取到院系下拉框选择的值
var college = Convert.ToString(obj["ext_parent_college"]);

if (string.IsNullOrEmpty(college))
return "";

// 拼接查询数据源条件,院系是专业对象的一个字段,查询时拼接到专业数据查询条件中
context.AndFilter = FilterBuilder.Eq("ext_college", college);

return null;
}
}

方案三(复杂场景,灵活匹配)​

使用多路分支组件,根据不同的条件分支选用不同的数据源。

适用于各种各样的数据源,并且后续的数据源还可以选择完全不同对象或毫不相干的数据源。

多路分支是更为强大的组件,可以完全覆盖几乎全部使用场景,但由于需要使用脚本,对于脚本开发没有经验的人来说不是十分友好,上手较为困难。因此,如果方案一能满足,优先使用方案一。

多路分支脚本设置​

using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using Chameleon.Common;
using Chameleon.Common.Context;
using Chameleon.Common.Exceptions;
using Chameleon.Common.Models;
using Chameleon.Database;

public class ChameleonCSharpScript
{
public string Execute(ComponentContext context, IChameleonDbContext dbContext, ILogger logger)
{
// 表单的字段值可以在请求体中获取到
var obj = context.Request?.List?.FirstOrDefault();

if (obj == null)
return "";

// 从参数中获取到院系下拉框选择的值
var college = Convert.ToString(obj["ext_parent_college"]);

if (string.IsNullOrEmpty(college))
return "";

// 拼接查询数据源条件,院系是专业对象的一个字段,查询时拼接到专业数据查询条件中
// 也可以在匹配分支后面加C#脚本组件来设置值,但为了方便,也可以在此直接设置
context.AndFilter = FilterBuilder.Eq("ext_college", college);

// 返回匹配标识,用于下游多路分支,这里值随意,但要和下游匹配值相同
return "1";
}
}

方案对比​

方案适用场景优点缺点
方案一静态数据源,参数可穷举配置简单直接,无需编写脚本仅适用于固定值场景
方案二单实体数据源,动态参数灵活性高,可动态拼接查询条件需要编写C#脚本
方案三复杂场景,多数据源最灵活,支持不同对象的数据源配置复杂,需要编写脚本

注意事项​

  • 优先使用方案一,配置简单且易于维护
  • 如果参数不可穷举,选择方案二或方案三
  • C#脚本中可以通过 context.Request?.List?.FirstOrDefault() 获取表单字段值
  • 使用 context.AndFilter 拼接查询条件
  • 确保接口已保存并发布后才能在表单中使用