2sxc:CarBrand字段值变更时重新运行公式更新CarModel下拉选项
解决CarBrand变更时自动触发车型API请求的问题
核心思路
让自定义函数显式依赖CarBrand字段的值,表单会自动监测该参数的变化,一旦CarBrand下拉值变更就重新执行函数,完全不需要手动调用context.form.runFormulas(),从根源上避免循环问题。同时通过缓存优化,减少重复API调用。
代码实现示例
1. 带缓存的自定义函数
// 全局缓存对象,用品牌唯一ID作为键存储对应车型 const carModelCache = {}; // 防止同一品牌重复发起请求的临时存储 const pendingRequests = {}; async function getCarModelsByBrand(carBrand) { // 品牌为空时返回空下拉选项 if (!carBrand?.id) return []; const brandId = carBrand.id; // 优先返回缓存数据 if (carModelCache[brandId]) { return carModelCache[brandId]; } // 避免同一品牌同时发起多个请求 if (pendingRequests[brandId]) { return await pendingRequests[brandId]; } try { // 发起API请求并缓存Promise,防止重复请求 pendingRequests[brandId] = fetch(`/api/car-models?brandId=${brandId}`) .then(res => res.json()) .then(models => { // 将请求结果存入缓存 carModelCache[brandId] = models.map(model => ({ label: model.name, value: model.code })); delete pendingRequests[brandId]; return carModelCache[brandId]; }); return await pendingRequests[brandId]; } catch (error) { console.error('获取车型列表失败:', error); delete pendingRequests[brandId]; return []; } }
2. 绑定到CarModel字段的公式
直接在CarModel字段的公式配置中引用该函数,传入CarBrand字段的值:
getCarModelsByBrand($CarBrand)
关键说明
- 自动触发更新:因为函数的参数是
$CarBrand,表单会自动监听这个字段的变化,一旦品牌选择变更,就会重新执行函数,无需手动调用公式刷新方法,彻底避免循环问题。 - 缓存逻辑:用品牌的唯一ID作为缓存键(而非品牌名称),避免同名品牌的数据冲突;同时通过
pendingRequests防止同一品牌短时间内重复发起API请求。 - 适配异步场景:如果你的表单平台支持异步公式,上述异步函数可直接使用;若仅支持同步,可改用同步请求方式(需确认API支持同步调用)。
额外优化
如果后续需要更新品牌对应的车型数据(比如品牌数据源有更新),可以手动清除对应品牌的缓存:
// 清除单个品牌的缓存 delete carModelCache[targetBrandId]; // 或者清空全部缓存 Object.keys(carModelCache).forEach(key => delete carModelCache[key]);
内容的提问来源于stack exchange,提问作者João Gomes
相关产品推荐
相关产品推荐

