es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Esquema JSON / sub-esquemas dependientes Formly

Este problema es un poco complicado de describir, así que ten paciencia y por favor haz preguntas si me falta algo…

Digamos que tienes un objeto json que define una lista de características, cada característica tiene las mismas tres propiedades pero tiene una propiedad que tiene una estructura completamente diferente. Por ejemplo:

La estructura real de cada característica no es relevante. Solo intento expresar esto a través de un esquema json en el que la estructura de configurationData para cada característica depende o está dictada por el valor de identificación de característica de su padre.

EDIT: Supongo que técnicamente no necesita depender, siempre y cuando ambas estructuras de configurationData sean un esquema válido para esa propiedad en el esquema de característica en sí. Además, los tipos en configurationData no son arbitrarios, siempre serían uno de los dos tipos para una característica específica en este ejemplo.

Sin embargo, esto debe estructurarse de una manera que se pueda expresar a través de Formly, ya que lo estoy usando para generar formularios. En este caso, sería una matriz de ObjectFieldTypes, uno para la característica a y otro para la característica b, que enumeraría las tres propiedades y proporcionaría tipos de campo Input, hasta que llegara a configurationData, momento en el que usaría un ObjectFieldType nuevamente, que ahora sería diferente para cada tipo de campo.

El problema aquí es que 1) no estoy seguro de cómo expresar esto en el esquema json y 2) no puedo usar cosas como patternProperties con formly porque las propiedades deben definirse explícitamente en el esquema json para que formly renderice los tipos de campo para cada propiedad. Aunque patternProperties sería técnicamente un esquema válido en este caso, si el esquema no define esas propiedades, entonces el modelo en el observable valueChanges en FormGroup las omite por completo. Así que terminaría con:

He intentado la construcción de if then else, pero no sé si el esquema está mal o si formly simplemente no lo admite. Hice un stack blitz para esto a continuación:

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Como experto en IT especializado en json, jsonschema, angular-formly y ngx-formly, el problema descrito trata de cómo expresar un objeto json que define una lista de características con diferentes estructuras de configurationData dependiendo del valor de la id de la característica padre usando json schema, y cómo usar Formly para generar formularios con diferentes tipos de campo para cada propiedad de configurationData de las características.

    Un enfoque para expresar esto en json schema es usar la construcción “if-then-else”, que permite definir diferentes subesquemas según ciertas condiciones. En este caso, podemos definir dos subesquemas que coincidan con el objeto configurationData basado en el valor de la id de la característica:

    "if": {
        "properties": {
          "id": { "const": "feature-a" }
        }
      },
      "then": {
        "properties": {
          "configurationData": {
            "type": "object",
            "properties": {
              "featureAConfigPropertyA": { "$ref": "#/definitions/featureAConfigPropertyASchema" },
              "featureAConfigPropertyB": { "type": "string" }
            }
          }
        }
      },
      "else": {
        "properties": {
          "configurationData": {
            "type": "object",
            "properties": {
              "featureBConfigArrayPropertyA": { "type": "array", "items": { "type": "string" } },
              "featureBConfigPropertyB": { "type": "array", "items": { "$ref": "#/definitions/featureBConfigPropertyBSchema" } }
            }
          }
        }
      }
    

    Aquí, comprobamos si la propiedad “id” es igual a “feature-a”, y si es así, definimos el esquema del objeto “configurationData” con dos propiedades: “featureAConfigPropertyA” y “featureAConfigPropertyB”. De lo contrario, definimos el esquema del objeto “configurationData” con dos propiedades diferentes: “featureBConfigArrayPropertyA”, que es un array de strings, y “featureBConfigPropertyB”, que es un array de objetos que coinciden con una cierta definición de esquema (“featureBConfigPropertyBSchema”).

    Además, necesitamos definir definiciones de esquema para cada tipo de propiedad de configurationData:

    "definitions": {
        "featureAConfigPropertyASchema": {
          "type": "object",
          "properties": {
            "somePrperty": { "type": "string" },
            "anotherProperty": { "type": "boolean" }
          }
        },
        "featureBConfigPropertyBSchema": {
          "type": "object",
          "properties": {
            "id": { "type": "string" },
            "name": { "type": "string" },
            "description": { "type": "string" },
            "enabled": { "type": "boolean" }
          }
        }
      }
    

    Una vez que tenemos definido el json schema, podemos usar Formly para generar formularios con diferentes tipos de campo para cada propiedad de configurationData de las características. Sin embargo, necesitamos definir explícitamente cada propiedad en el json schema para que Formly pueda renderizar los tipos de campo para cada propiedad. No podemos usar patternProperties en este caso porque Formly excluye las propiedades que no están definidas explícitamente en el json schema. Por lo tanto, necesitamos definir cada propiedad manualmente, como:

    {
      key: 'features',
      type: 'array',
      templateOptions: { label: 'Características' },
      fieldArray: {
        fieldGroup: [
          { key: 'id', type: 'input', templateOptions: { label: 'ID' } },
          { key: 'enabled', type: 'checkbox', templateOptions: { label: 'Habilitado' } },
          {
            key: 'configurationData',
            type: 'object',
            fieldGroup: [
              { key: 'featureAConfigPropertyA', type: 'input', templateOptions: { label: 'Propiedad A de Configuración de la Característica A' } },
              { key: 'featureAConfigPropertyB', type: 'input', templateOptions: { label: 'Propiedad B de Configuración de la Característica A' } },
              { key: 'featureBConfigArrayPropertyA', type: 'input', templateOptions: { label: 'Propiedad Array A de Configuración de la Característica B' } },
              {
                key: 'featureBConfigPropertyB',
                type: 'array',
                templateOptions: { label: 'Propiedad B de Configuración de la Característica B' },
                fieldArray: {
                  fieldGroup: [
                    { key: 'id', type: 'input', templateOptions: { label: 'ID' } },
                    { key: 'name', type: 'input', templateOptions: { label: 'Nombre' } },
                    { key: 'description', type: 'input', templateOptions: { label: 'Descripción' } },
                    { key: 'enabled', type: 'checkbox', templateOptions: { label: 'Habilitado' } },
                  ]
                }
              }
            ]
          }
        ]
      }
    }
    

    Aquí, definimos un ArrayFieldType para la propiedad “features”, y para cada objeto de característica, definimos tres tipos de campo: un InputFieldType para la propiedad “id”, un CheckboxFieldType para la propiedad “enabled”, y un ObjectFieldType para la propiedad “configurationData”. Para la propiedad “configurationData”, definimos cuatro tipos de campo: dos InputFieldTypes para las propiedades “featureAConfigPropertyA” y “featureAConfigPropertyB”, un InputFieldType para la propiedad “featureBConfigArrayPropertyA”, y un ArrayFieldType para la propiedad “featureBConfigPropertyB”, que consta de un ObjectFieldType con cuatro propiedades: “id”, “name”, “description” y “enabled”.

    En conclusión, para manejar un objeto json que define una lista de características con diferentes estructuras de configurationData dependiendo del valor de la id de la característica padre usando json schema y Formly, necesitamos usar la construcción “if-then-else” en json schema para definir diferentes subesquemas para cada propiedad de configurationData de las características, y necesitamos definir manualmente cada propiedad en el json schema para permitir que Formly genere formularios con diferentes tipos de campo para cada propiedad.

Comments are closed.