lljj-x / vue-json-schema-form

基于Vue/Vue3,Json Schema 和 ElementUi/antd/iview3/naiveUi 等生成 HTML Form 表单,用于活动编辑器、h5编辑器、cms等数据配置;支持可视化生成表单Schema 。 Generate a form using Vue/Vue3, Json Schema and ElementUi/antdv/iview3/naiveUi
https://form.lljj.me/
Apache License 2.0
2.01k stars 418 forks source link

AnyOf/OneOf 子节点为`$ref`时,选项标题是“选项1、2...”,而非子节点的 `title` #354

Open laorange opened 3 months ago

laorange commented 3 months ago

vue和ui框架

Vue2 & Vue3 + 所有ui框架 均能在playground复现该问题

问题描述

如下图所示,AnyOf/OneOf 子节点为$ref时,期望显示:“类型A、类型B”(子节点的 title),而不是“选项1、选项2”;

与RJSF中的表现有较大差异

vjsf-issue-tiny

如何复现

可用于复现的json-schema(对应Playground的链接):

{"$defs":{"ClassA":{"properties":{"fooA":{"default":0,"title":"ClassA的属性","type":"number"}},"title":"类型A","type":"object"},"ClassB":{"properties":{"fooB":{"default":0,"title":"ClassB的属性","type":"number"}},"title":"类型B","type":"object"}},"properties":{"common":{"oneOf":[{"$ref":"#/$defs/ClassA"},{"$ref":"#/$defs/ClassB"}],"title":"OneOf属性","description":"A/B类型二选一"}},"title":"OneOf模型测试","type":"object"}

该json的格式为:

vjsf-issue-json-schema-tiny

初步排查结果

初步排出:该问题是因为子节点为$ref;对比测试为:直接使用对应的Object内容而非$ref,使用以下json-schema能够正常显示(对应的Playground):

{"properties":{"common":{"oneOf":[{"properties":{"fooA":{"default":0,"title":"ClassA的属性","type":"number"}},"title":"类型A","type":"object"},{"properties":{"fooB":{"default":0,"title":"ClassB的属性","type":"number"}},"title":"类型B","type":"object"}],"title":"OneOf属性","description":"A/B类型二选一"}},"title":"OneOf模型测试","type":"object"}

期望的结果

😄希望与RJSF中展示效果相仿,能在选项中展示子节点的title,期待您的回复🫡

laorange commented 3 months ago

经过进一步测试,初步排出:该问题是因为子节点为$ref

对比测试,直接使用对应的Object内容而非$ref对应的Playground中能够正常显示:

{
    "properties": {
        "common": {
            "oneOf": [
                {
                    "properties": {
                        "fooA": {
                            "default": 0,
                            "title": "ClassA的属性",
                            "type": "number"
                        }
                    },
                    "title": "类型A",
                    "type": "object"
                },
                {
                    "properties": {
                        "fooB": {
                            "default": 0,
                            "title": "ClassB的属性",
                            "type": "number"
                        }
                    },
                    "title": "类型B",
                    "type": "object"
                }
            ],
            "title": "OneOf属性",
            "description": "A/B类型二选一"
        }
    },
    "title": "OneOf模型测试",
    "type": "object"
}
lljj-x commented 2 months ago

子节点不是 $ref 的时候是可以正常取到标题的对吧 ?

laorange commented 2 months ago

子节点不是 $ref 的时候是可以正常取到标题的对吧 ?

😄是的,上面提到的两个对比测试:

lljj-x commented 2 months ago

这周处理下

lljj-x commented 2 months ago

大致看了下,应该是 这里的schema 没有经过retrieve方法处理,要看看哪里处理合适,如果你有兴趣的话 也可以贡献代码

https://github.com/lljj-x/vue-json-schema-form/blob/master/packages/lib/vue2/vue2-core/src/fields/combiningSchemas/SelectLinkageField/index.js#L71C33-L71C39

类似下面

retrieveSchema(xxxx)