Saya membaca objek JSON dari server REST jauh. Objek JSON ini memiliki semua properti dari kelas naskah (menurut desain). Bagaimana cara melemparkan objek JSON yang diterima ke tipe var?
Saya tidak ingin mengisi var naskah (yaitu memiliki konstruktor yang mengambil objek JSON ini). Ini besar dan menyalin segala sesuatu di seluruh sub-objek dengan sub-objek & properti dengan properti akan membutuhkan banyak waktu.
Pembaruan: Namun Anda dapat melemparkannya ke antarmuka naskah!
json
typescript
David Thielen
sumber
sumber
Jawaban:
Anda tidak dapat dengan mudah memasukkan hasil JavaScript lama-polos dari permintaan Ajax ke instance kelas JavaScript / TypeScript. Ada sejumlah teknik untuk melakukannya, dan umumnya melibatkan menyalin data. Kecuali Anda membuat instance kelas, itu tidak akan memiliki metode atau properti. Ini akan tetap menjadi objek JavaScript sederhana.
Sementara jika Anda hanya berurusan dengan data, Anda bisa melakukan cast ke antarmuka (karena ini murni struktur waktu kompilasi), ini akan mengharuskan Anda menggunakan kelas TypeScript yang menggunakan instance data dan melakukan operasi dengan data itu.
Beberapa contoh menyalin data:
Intinya, Anda baru saja:
sumber
JSON.parse()
. Keduanya masih perlu dilakukan, tetapi secara sintaksis keduanya dapat digabungkan.Object.setPrototypeOf
Saya memiliki masalah yang sama dan saya telah menemukan perpustakaan yang melakukan pekerjaan: https://github.com/pleerock/class-transformer .
Ini berfungsi seperti ini:
Ini mendukung anak-anak yang bersarang tetapi Anda harus mendekorasi anggota kelas Anda.
sumber
@Type
penjelasan Anda ). Jawaban ini layak mendapat kredit lebih banyak.Dalam TypeScript Anda dapat melakukan pernyataan tipe menggunakan antarmuka dan generik seperti:
Di mana ILocationMap menjelaskan bentuk data Anda. Keuntungan dari metode ini adalah bahwa JSON Anda bisa mengandung lebih banyak properti tetapi bentuknya memenuhi kondisi antarmuka.
Saya harap itu membantu!
sumber
Jika Anda menggunakan ES6, coba ini:
Tetapi cara ini tidak akan bekerja pada objek sarang , sedihnya.
sumber
Object.create(MyClass.prototype)
, melewati konstruktor sama sekali.Saya menemukan artikel yang sangat menarik tentang pengecoran generik JSON ke Kelas Script:
http://cloudmark.github.io/Json-Mapping/
Anda berakhir dengan kode berikut:
sumber
TLDR: Satu liner
Jawaban Terperinci
Saya tidak akan merekomendasikan pendekatan Object.assign, karena dapat secara tidak tepat mengotori instance kelas Anda dengan properti yang tidak relevan (serta penutupan yang ditentukan) yang tidak dideklarasikan di dalam kelas itu sendiri.
Di kelas Anda mencoba deserialize ke, saya akan memastikan properti apa pun yang Anda inginkan deserialized didefinisikan (null, array kosong, dll). Dengan mendefinisikan properti Anda dengan nilai awal, Anda mengekspos visibilitas mereka ketika mencoba untuk mengulangi anggota kelas untuk memberikan nilai (lihat metode deserialize di bawah).
Pada contoh di atas, saya cukup membuat metode deserialize. Dalam contoh dunia nyata, saya akan membuatnya terpusat di kelas dasar yang dapat digunakan kembali atau metode layanan.
Berikut adalah cara memanfaatkan ini dalam sesuatu seperti resp http ...
Jika tslint / ide mengeluh tentang tipe argumen yang tidak kompatibel, cukup masukkan argumen ke tipe yang sama menggunakan kurung sudut
<YourClassName>
, contoh:Jika Anda memiliki anggota kelas yang memiliki tipe tertentu (alias: instance dari kelas lain), maka Anda dapat meminta mereka memasukkannya ke dalam instance yang diketik melalui metode pengambil / penyetel.
Contoh di atas akan menghapus daftar sertifikat dan daftar tugas ke dalam instance kelas masing-masing.
sumber
Dengan asumsi json memiliki properti yang sama dengan kelas naskah Anda, Anda tidak perlu menyalin properti Json Anda ke objek naskah Anda. Anda hanya perlu membangun objek skrip Anda melewati data json di konstruktor.
Dalam panggilan balik ajax Anda, Anda menerima perusahaan:
Untuk membuatnya bekerja:
1) Tambahkan konstruktor di kelas naskah Anda yang menggunakan data json sebagai parameter. Dalam konstruktor yang Anda memperpanjang objek json Anda dengan jQuery, seperti ini:
$.extend( this, jsonData)
. $ .extend memungkinkan menjaga prototipe javascript sambil menambahkan properti objek json.2) Catatan Anda harus melakukan hal yang sama untuk objek yang ditautkan. Dalam kasus Karyawan dalam contoh, Anda juga membuat konstruktor yang mengambil bagian dari data json untuk karyawan. Anda memanggil $ .map untuk menerjemahkan karyawan json ke objek naskah skrip Karyawan.
Ini adalah solusi terbaik yang saya temukan ketika berhadapan dengan kelas-kelas TypeScript dan objek json.
sumber
Tidak ada yang belum secara otomatis memeriksa apakah objek JSON yang Anda terima dari server memiliki properti antarmuka typescript yang diharapkan (baca sesuai dengan). Tapi Anda bisa menggunakannya Penjaga Tipe Buatan Pengguna
Mempertimbangkan antarmuka berikut dan objek json konyol (bisa jenis apa saja):
Tiga cara yang mungkin:
A. Ketikkan Penegasan atau pemeran statis sederhana yang ditempatkan setelah variabel
B. Pemain statis sederhana, sebelum variabel dan antara berlian
C. Pemain dinamis canggih, Anda memeriksa sendiri struktur objek
Anda dapat bermain dengan contoh ini di sini
Perhatikan bahwa kesulitannya adalah menulis
isMyInterface
fungsi. Saya berharap TS akan menambahkan dekorator cepat atau lambat untuk mengekspor pengetikan kompleks ke runtime dan membiarkan runtime memeriksa struktur objek saat diperlukan. Untuk saat ini, Anda bisa menggunakan validator skema json yang tujuannya kira-kira sama ATAU generator fungsi pemeriksaan tipe runtime inisumber
Dalam kasus saya ini berfungsi. Saya menggunakan fungsi Object.assign (target, sumber ...) . Pertama, pembuatan objek yang benar, kemudian menyalin data dari objek json ke target. Contoh:
Dan contoh penggunaan yang lebih maju. Contoh menggunakan array.
sumber
this.users[i] = new User(); Object.assign(this.users[i], users[i])
this.users[i] = Object.assign(new User(), users[i]);
Meskipun tidak casting per se; Saya telah menemukan https://github.com/JohnWhiteTB/TypedJSON sebagai alternatif yang bermanfaat.
sumber
Anda bisa membuat
interface
tipe Anda (SomeType
) dan melemparkan objek ke dalamnya.sumber
Jika Anda perlu melemparkan objek json Anda ke kelas naskah dan memiliki metode instance yang tersedia di objek yang dihasilkan yang perlu Anda gunakan
Object.setPrototypeOf
, seperti yang saya lakukan dalam potongan kode di bawah:sumber
Pertanyaan lama dengan sebagian besar jawaban yang benar, tetapi tidak terlalu efisien. Inilah yang saya usulkan:
Buat kelas dasar yang berisi metode init () dan metode cast statis (untuk objek tunggal dan array). Metode statis bisa di mana saja; versi dengan kelas dasar dan init () memungkinkan ekstensi yang mudah sesudahnya.
Mekanika serupa (dengan assign () ) telah disebutkan dalam pos @ Adam111p. Hanya cara lain (lebih lengkap) untuk melakukannya. @Timothy Perez kritis terhadap assign () , tetapi jika itu sepenuhnya sesuai di sini.
Menerapkan kelas turunan (nyata):
Sekarang kita bisa melemparkan objek yang diambil dari layanan:
Semua hierarki objek SubjectArea akan memiliki kelas yang benar.
Sebuah use case / example; buat layanan Angular (kelas dasar abstrak lagi):
Penggunaannya menjadi sangat sederhana; buat layanan Area:
get () metode layanan akan mengembalikan Janji array yang sudah dilemparkan sebagai objek SubjectArea (seluruh hierarki)
Sekarang katakanlah, kita memiliki kelas lain:
Membuat layanan yang mengambil data dan melakukan cast ke kelas yang benar adalah sesederhana:
sumber
Gunakan kelas yang diperluas dari antarmuka.
Kemudian:
Dan terbaik:
ToWhat menjadi pengontrol DataInterface.
sumber
https://jvilk.com/MakeTypes/
Anda dapat menggunakan situs ini untuk menghasilkan proxy untuk Anda. ini menghasilkan kelas dan dapat mengurai dan memvalidasi objek JSON input Anda.
sumber
Dalam lates TS Anda dapat melakukan hal ini:
Dan daripada pengguna seperti ini:
sumber
Saya bertemu dengan kebutuhan yang sama. Saya menginginkan sesuatu yang akan memberi saya transformasi mudah dari / ke JSON yang berasal dari panggilan api REST ke / dari definisi kelas tertentu. Solusi yang saya temukan tidak cukup atau dimaksudkan untuk menulis ulang kode kelas saya dan menambahkan anotasi atau similars.
Saya ingin sesuatu seperti GSON digunakan di Jawa untuk membuat serial / deserialize kelas ke / dari objek JSON.
Dikombinasikan dengan kebutuhan nanti, bahwa konverter akan berfungsi di JS juga, saya akhirnya menulis paket saya sendiri.
Meskipun demikian, sedikit overhead. Tetapi ketika mulai sangat nyaman dalam menambah dan mengedit.
Anda menginisialisasi modul dengan:
Kemudian dalam kode Anda, Anda menggunakan modul yang diinisialisasi seperti:
atau, ke JSON:
Gunakan tautan ini ke paket npm dan juga penjelasan terperinci tentang cara bekerja dengan modul: json-class-converter
Juga dibungkus untuk
penggunaan sudut dalam: angular-json-class-converter
sumber
Berikan objek apa adanya ke konstruktor kelas; Tidak ada konvensi atau pemeriksaan
sumber
Anda dapat menggunakan paket npm ini. https://www.npmjs.com/package/class-converter
Mudah digunakan, misalnya:
sumber
Secara pribadi saya menemukan itu mengerikan bahwa naskah tidak mengizinkan definisi titik akhir untuk menentukan jenis objek yang diterima. Tampaknya memang demikian, saya akan melakukan apa yang telah saya lakukan dengan bahasa lain, dan itu adalah bahwa saya akan memisahkan objek JSON dari definisi kelas, dan meminta definisi kelas menggunakan objek JSON sebagai satu-satunya anggota data .
Saya membenci kode boilerplate, jadi bagi saya biasanya masalah mendapatkan hasil yang diinginkan dengan jumlah kode paling sedikit sambil mempertahankan tipe.
Pertimbangkan definisi struktur objek JSON berikut - ini adalah apa yang akan Anda terima pada titik akhir, mereka hanya definisi struktur, tidak ada metode.
Jika kita memikirkan hal-hal di atas dalam istilah berorientasi objek, antarmuka di atas bukan kelas karena mereka hanya mendefinisikan struktur data. Kelas dalam istilah OO mendefinisikan data dan kode yang beroperasi di atasnya.
Jadi sekarang kita mendefinisikan kelas yang menentukan data dan kode yang beroperasi di dalamnya ...
Dan sekarang kita bisa dengan mudah melewati objek apa pun yang sesuai dengan struktur IPerson dan berada di jalan kita ...
Dengan cara yang sama kita sekarang dapat memproses objek yang diterima di titik akhir Anda dengan sesuatu di sepanjang ...
Ini jauh lebih berkinerja dan menggunakan setengah memori menyalin data, sementara secara signifikan mengurangi jumlah kode boilerplate Anda harus menulis untuk setiap jenis entitas. Itu hanya bergantung pada keamanan jenis yang disediakan oleh TypeScript.
sumber
Gunakan deklarasi 'sebagai':
sumber
MyClass
.Ini adalah pilihan yang sederhana dan sangat bagus
Dan kemudian Anda akan memilikinya
sumber
Saya menggunakan perpustakaan ini di sini: https://github.com/pleerock/class-transformer
Penerapan:
Terkadang Anda harus menguraikan nilai JSON untuk plainToClass untuk memahami bahwa itu adalah data yang diformat JSON
sumber
Saya menggunakan Angular 6 di aplikasi frontend dan Spring Boot di backend yang mengembalikan Java Objects. Yang perlu saya lakukan adalah mendefinisikan kelas yang sama pada aplikasi sudut yang memiliki properti yang cocok dan kemudian saya dapat menerima objek 'sebagai' objek kelas sudut ( comp sebagai Perusahaan dalam contoh di bawah).
Lihat kode ujung depan di bawah misalnya. Beri tahu saya di komentar jika ada yang perlu lebih jelas.
di mana perusahaan adalah objek entitas dalam aplikasi boot musim semi dan juga kelas di Angular.
sumber