【问题标题】:Map dependencies in JSON structureJSON结构中的映射依赖关系
【发布时间】:2019-04-18 11:27:37
【问题描述】:

我目前正在构建一个网络工具,它使用户能够以字符串的形式生成选项包。为了选择他想要的选项,他使用了一个具有不同输入(单选、复选框)的表单,该表单由dictionary.json 生成,该dictionary.json 当前包含所有可用选项及其代码,格式如下(可能会更改):

[

    {
        "id": 0001,
        "title":"foo",
        "type":"radio",
        "options":[
            {
                "bar":"",
                "foo":"489",
                "foobar":"489+490"
            }
        ]
    },
    {
        "id": 0002,
        "title":"something",
        "type":"check",
        "options":[
            {
                "everything":"M016",
                "evenmore":"M139"
            }
        ]
    },

    [...]

如您所见,它基本上是一个小型数据库。问题是这些选项相互依赖,所以如果foofoobar,它可能会确定something 肯定是evenmore 并且不能更改为everything如何在dictionary.json 中映射这些依赖项,以便生成的表单能够可靠地将由其他选项确定的选项变灰?

结构必须灵活,以便可以插入新的依赖项,并可靠地生成新表单或根据它们验证现有输出。也可能存在依赖于多个其他选项的选项。我想不出保存这些依赖项的聪明方法,我想知道 JSON 是否适合在这里使用。

欢迎任何提示或想法。谢谢!

【问题讨论】:

  • 我建议看看 Joi:npmjs.com/package/@hapi/joi。您可以使用非常复杂且可扩展的 joi 模式来验证几乎任何 JSON 对象。
  • @AnandUndavia 感谢您的评论。我不确定这将如何应用在这里,因为发生的唯一验证是规则集(字符串)是否“允许”,如“它不包含相互排除的规则”
  • 这些选项是单个对象专有的还是 "type" 专有的?例如。 "bar" 选项可以出现在其他对象和/或类型上吗?

标签: javascript json database data-structures structure


【解决方案1】:

您可以尝试将每个选项保存为一个对象,该对象存储所有选项,如果选择该选项,这些选项将被排除。 因此,您的 JSON 可能如下所示:

[
    {
        "id": 0001,
        "title":"foo",
        "type":"radio",
        "options":[
            {
                "bar":"",
                "excludes": []
            },
            {
                "foo":"489",
                "excludes": []
            },
            {
                "foobar":"489+490",
                "excludes": [
                    {
                        "id": 0002,
                        "options": [
                            "everything"
                        ],
                    },
                    {
                        "id": 0003,
                        "options": [
                            "apple",
                            "cherry"
                        ],
                    },
                ]
            }
        ]
    },
    {
        "id": 0002,
        "title":"something",
        "type":"check",
        "options":[
            {
                "everything":"M016",
                "excludes": []
            },
            {
                "evenmore":"M139",
                "excludes": []
            }
        ]
    },

    [...]

每次选择一个选项时,您都必须检查其排除列表并禁用特定字段的所有这些选项。
为了提高可用性,您可以检查一个字段只剩下一个选项,选择此选项,然后禁用整个字段。

编辑: 此外,您可以为每个选项保存一个 isExcludedBy 字段。
id 0002everything 选项将如下所示:

"isExcludedBy": [
    "id": 0001,
    "options": [
        "foobar"
    ]
]

这有点多余,但根据您希望 UI 显示的内容,它可以为您节省一些计算时间。

【讨论】:

    【解决方案2】:

    一个可能的简单解决方案(回答您的问题):

    // dictionary.json
    {
        "options": [
            {
                "id": 0001,
                "title":"foo",
                "type":"radio",
                "options":[
                    {
                        "bar":"",
                        "foo":"489",
                        "foobar":"489+490"
                    }
                ]
            }
            // etc.; same as before
        ],
        // this is it:
        "dependencies": [
            [["0001", "foobar"], ["0002", "evenmore"]],
        ]
    }
    

    dependencies 这里由成对的 [options 中的选项路径,暗示另一个选项隐含选项的路径]组成。 您可以直接从中创建一个Map 数据结构(隐含选项是键,隐含的是值)。

    这假设一个选项只能暗示另一个选项(但它仍然允许 依赖于多个其他选项的选项)。

    您当然可以像这样轻松扩展它:

    [["0001", "foobar"], [["0002", "evenmore"], ["0003", "namaste"]]]
    

    这意味着"0001"/"foobar" 暗示"0002"/"evenmore""0003"/"namaste"。但也许是 YAGNI。 :)

    【讨论】:

      【解决方案3】:

      解决此问题的一种方法是对您实际表达的域进行建模,并基于此生成表单。例如,我们知道公寓有街道编号和公寓编号,而船屋甚至没有街道。

      {
          "dwelling": {
              "type": "houseboat",
              "latitude": null,
              "longitude": null,
          }
      }
      

      {
         "dwelling": {
             "type": "apartment",
             "street": "Beech St.",
             "street_number": 123,
             "apartment_number": 207,
         }
      }
      

      通过对域而不是表单进行建模,您可以编写适用于表单之外的规则,并且您不必开发一种微型语言来表达表单依赖关系。

      【讨论】:

      • 您将如何使用这种方法解决依赖关系?
      • @omel09 你不需要用这种方法表达依赖关系。您将有一个用于渲染船屋的例程和另一个用于渲染公寓的例程。船屋渲染不包含门牌号,公寓渲染不包含经度。
      猜你喜欢
      • 2015-09-21
      • 2020-10-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-28
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多