Leí un objeto JSON de un servidor REST remoto. Este objeto JSON tiene todas las propiedades de una clase de mecanografiado (por diseño). ¿Cómo envío ese objeto JSON recibido a un tipo var?
No quiero rellenar un var de mecanografiado (es decir, tener un constructor que tome este objeto JSON). Es grande y copiar todo en un subobjeto por subobjeto y propiedad por propiedad llevaría mucho tiempo.
Actualización: ¡Sin embargo, puede enviarlo a una interfaz de mecanografía!
json
typescript
David Thielen
fuente
fuente
Respuestas:
No puede simplemente transmitir un resultado de JavaScript simple desde una solicitud de Ajax a una instancia prototipo de clase JavaScript / TypeScript. Existen varias técnicas para hacerlo, y generalmente implican copiar datos. A menos que cree una instancia de la clase, no tendrá ningún método o propiedades. Seguirá siendo un simple objeto JavaScript.
Si bien solo se tratara de datos, simplemente podría hacer una conversión a una interfaz (ya que es puramente una estructura de tiempo de compilación), esto requeriría que use una clase TypeScript que use la instancia de datos y realice operaciones con esos datos.
Algunos ejemplos de copia de datos:
En esencia, simplemente:
fuente
JSON.parse()
. Ambos aún tendrían que hacerse, pero sintácticamente podrían combinarse.Object.setPrototypeOf
Tuve el mismo problema y encontré una biblioteca que hace el trabajo: https://github.com/pleerock/class-transformer .
Funciona así :
Es compatible con niños anidados, pero debe decorar el miembro de su clase.
fuente
@Type
embargo, no olvide sus anotaciones). Esta respuesta merece más crédito.En TypeScript puede hacer una aserción de tipo usando una interfaz y genéricos de la siguiente manera:
Donde ILocationMap describe la forma de sus datos. La ventaja de este método es que su JSON podría contener más propiedades pero la forma satisface las condiciones de la interfaz.
¡Espero que eso ayude!
fuente
Si está utilizando ES6, intente esto:
Pero de esta manera no funcionará en el objeto del nido , lamentablemente.
fuente
Object.create(MyClass.prototype)
, evitando el constructor por completo.Encontré un artículo muy interesante sobre la conversión genérica de JSON a una clase de tipografía:
http://cloudmark.github.io/Json-Mapping/
Terminas con el siguiente código:
fuente
TLDR: un revestimiento
La respuesta detallada
Yo no recomendar el enfoque Object.assign, ya que puede inapropiadamente la basura su instancia de clase con propiedades irrelevantes (así como los cierres definidos) que se declaró no dentro de la propia clase.
En la clase en la que intenta deserializarse, me aseguraría de que se definan las propiedades que desea deserializar (nula, matriz vacía, etc.). Al definir sus propiedades con valores iniciales, expone su visibilidad cuando intenta iterar a los miembros de la clase para asignarles valores (consulte el método de deserialización a continuación).
En el ejemplo anterior, simplemente creé un método de deserialización. En un ejemplo del mundo real, lo tendría centralizado en una clase base reutilizable o método de servicio.
Aquí es cómo utilizar esto en algo así como un http resp ...
Si tslint / ide se queja de que el tipo de argumento es incompatible, simplemente convierta el argumento en el mismo tipo usando paréntesis angulares
<YourClassName>
, por ejemplo:Si tiene miembros de clase que son de un tipo específico (también conocido como: instancia de otra clase), puede convertirlos en instancias escritas a través de métodos getter / setter.
El ejemplo anterior deserializará tanto el acct como la lista de tareas en sus respectivas instancias de clase.
fuente
Suponiendo que json tiene las mismas propiedades que su clase de mecanografiado, no tiene que copiar sus propiedades de Json a su objeto de mecanografiado. Solo tendrá que construir su objeto Typecript pasando los datos json en el constructor.
En su devolución de llamada ajax, recibe una empresa:
Para hacer que eso funcione:
1) Agregue un constructor en su clase de Script mecanografiado que tome los datos json como parámetro. En ese constructor a ampliar su objeto JSON con jQuery, así:
$.extend( this, jsonData)
. $ .extend permite mantener los prototipos de JavaScript al tiempo que agrega las propiedades del objeto json.2) Tenga en cuenta que tendrá que hacer lo mismo para los objetos vinculados. En el caso de Empleados en el ejemplo, también crea un constructor que toma la porción de los datos json para los empleados. Llama a $ .map para traducir empleados json a objetos de empleados mecanografiados.
Esta es la mejor solución que encontré al tratar con clases de Tipos de letra y objetos json.
fuente
Todavía no hay nada que verifique automáticamente si el objeto JSON que recibió del servidor tiene las propiedades de interfaz esperadas (leer se ajustan a). Pero puede usar protectores de tipo definidos por el usuario
Teniendo en cuenta la siguiente interfaz y un objeto json tonto (podría haber sido de cualquier tipo):
Tres formas posibles:
A. Tipo de aserción o molde estático simple colocado después de la variable
B. Molde estático simple, antes de la variable y entre diamantes.
C. Reparto dinámico avanzado, comprueba usted mismo la estructura del objeto.
Puedes jugar con este ejemplo aquí
Tenga en cuenta que la dificultad aquí es escribir la
isMyInterface
función. Espero que TS agregue un decorador tarde o temprano para exportar la escritura compleja al tiempo de ejecución y dejar que el tiempo de ejecución verifique la estructura del objeto cuando sea necesario. Por ahora, puede usar un validador de esquema json cuyo propósito es aproximadamente el mismo O este generador de función de verificación de tipo de tiempo de ejecuciónfuente
En mi caso funciona. Usé las funciones Object.assign (target, sources ...) . Primero, la creación del objeto correcto, luego copia los datos del objeto json al destino. Ejemplo:
Y un ejemplo más avanzado de uso. Un ejemplo usando la matriz.
fuente
this.users[i] = new User(); Object.assign(this.users[i], users[i])
this.users[i] = Object.assign(new User(), users[i]);
Si bien no está lanzando per se; He encontrado https://github.com/JohnWhiteTB/TypedJSON como una alternativa útil.
fuente
Puede crear uno
interface
de su tipo (SomeType
) y convertir el objeto en eso.fuente
Si necesita convertir su objeto json en una clase de mecanografiado y tener sus métodos de instancia disponibles en el objeto resultante que necesita usar
Object.setPrototypeOf
, como hice en el fragmento de código a continuación:fuente
Una vieja pregunta con respuestas en su mayoría correctas, pero no muy eficientes. Esto lo propongo:
Cree una clase base que contenga el método init () y los métodos de conversión estática (para un solo objeto y una matriz). Los métodos estáticos pueden estar en cualquier parte; La versión con la clase base y init () permite extensiones fáciles después.
Mecánicos similares (con asignar () ) se han mencionado en la publicación @ Adam111p. Solo otra forma (más completa) de hacerlo. @Timothy Perez es crítico de asignar () , pero en mi opinión, es completamente apropiado aquí.
Implemente una clase derivada (la real):
Ahora podemos lanzar un objeto recuperado del servicio:
Toda la jerarquía de objetos SubjectArea tendrá la clase correcta.
Un caso de uso / ejemplo; crear un servicio angular (clase base abstracta nuevamente):
El uso se vuelve muy simple; crear un servicio de área:
El método get () del servicio devolverá una Promesa de una matriz ya convertida como objetos SubjectArea (jerarquía completa)
Ahora digamos, tenemos otra clase:
Crear un servicio que recupera datos y se convierte en la clase correcta es tan simple como:
fuente
Use una clase extendida desde una interfaz.
Entonces:
Y lo mejor:
ToWhat se convierte en un controlador de DataInterface.
fuente
https://jvilk.com/MakeTypes/
puede usar este sitio para generar un proxy para usted. genera una clase y puede analizar y validar su objeto JSON de entrada.
fuente
En los últimos TS puedes hacer así:
Y que usuario como este:
fuente
Me encontré con una necesidad similar. Quería algo que me diera una fácil transformación de / a JSON que provenga de una llamada API REST a / desde una definición de clase específica. Las soluciones que he encontrado son insuficientes o pretenden reescribir el código de mis clases y agregar anotaciones o similares.
Quería algo como GSON se usa en Java para serializar / deserializar clases a / desde objetos JSON.
Combinado con una necesidad posterior, de que el convertidor funcionará también en JS, terminé de escribir mi propio paquete.
Sin embargo, tiene un poco de gastos generales. Pero cuando se inicia, es muy conveniente agregar y editar.
Inicializa el módulo con:
Luego, en su código, usa el módulo inicializado como:
o, a JSON:
Use este enlace al paquete npm y también una explicación detallada de cómo trabajar con el módulo: json-class-converter
También lo envolvió para
uso angular en: angular-json-class-converter
fuente
Pase el objeto como está al constructor de la clase; Sin convenciones ni controles
fuente
Puedes usar este paquete npm. https://www.npmjs.com/package/class-converter
Es fácil de usar, por ejemplo:
fuente
Personalmente, me parece terrible que el mecanografiado no permita que una definición de punto final especifique el tipo de objeto que se recibe. Como parece que este es el caso, haría lo que he hecho con otros idiomas, y es que separaría el objeto JSON de la definición de clase, y haría que la definición de clase usara el objeto JSON como su único miembro de datos .
Desprecio el código repetitivo, por lo que para mí generalmente se trata de obtener el resultado deseado con la menor cantidad de código mientras se conserva el tipo.
Considere las siguientes definiciones de estructura de objeto JSON: estas serían las que recibiría en un punto final, son solo definiciones de estructura, no métodos.
Si pensamos en lo anterior en términos orientados a objetos, las interfaces anteriores no son clases porque solo definen una estructura de datos. Una clase en términos OO define los datos y el código que opera en ellos.
Así que ahora definimos una clase que especifica datos y el código que opera en ellos ...
Y ahora simplemente podemos pasar cualquier objeto conforme a la estructura de IPerson y seguir nuestro camino ...
De la misma manera, ahora podemos procesar el objeto recibido en su punto final con algo parecido a ...
Esto es mucho más eficaz y utiliza la mitad de la memoria de la copia de datos, al tiempo que reduce significativamente la cantidad de código repetitivo que debe escribir para cada tipo de entidad. Simplemente se basa en la seguridad de tipo proporcionada por TypeScript.
fuente
Utilice la declaración 'como':
fuente
MyClass
.Esta es una opción simple y realmente buena
Y luego tendrás
fuente
Usé esta biblioteca aquí: https://github.com/pleerock/class-transformer
Implementación:
A veces tendrá que analizar los valores JSON para plainToClass para comprender que se trata de datos con formato JSON
fuente
Estoy usando Angular 6 en el frontend y la aplicación Spring Boot en el backend que devuelve Java Objects. Todo lo que necesito hacer es definir una clase similar en la aplicación angular que tenga propiedades coincidentes y luego puedo aceptar el objeto 'como' un objeto de clase angular ( comp como Empresa en el ejemplo a continuación).
Consulte el código de front-end a continuación, por ejemplo. Déjame saber en los comentarios si algo necesita más claridad.
donde empresa es un objeto de entidad en la aplicación de arranque de primavera y también es una clase en Angular.
fuente