TypeScript: إلغاء تسلسل JSON إلى فئات باستخدام التحقق من النوع على الخصائص

مرحبا يا هبر! أرغب في مشاركة مكتبتي معك لإلغاء تسلسل كائنات JSON إلى فئات ، والتي تتحقق أيضًا تلقائيًا من صحة بيانات الإدخال حسب النوع.

منذ وقت ليس ببعيد ، ظهر شيء رائع مثل الطبقات في جافا سكريبت ، مما سهل إلى حد كبير عملية كتابة التعليمات البرمجية. ولكن للأسف ، لم تظهر وظيفة إزالة ترميز JSON في هذه الفئات نفسها ، أي يمكنك إجراء تسلسل لفئة إلى سلسلة ، ولكن مرة أخرى بنفسك. ولإصلاح هذا العيب ، تمت كتابة المكتبة القابلة للتسلسل والتي أريد مشاركتها معك.

يظهر جوهر المشكلة في الكود التالي:

export class User { public firstName: string = ""; public lastName: string = ""; public birthDate: Date = new Date(); public getFullName(): string { return [this.firstName, this.lastName].join(' '); } public getAge(): number { return new Date().getFullYear() - this.birthDate.getFullYear(); } } const ivan = new User(); ivan.getFullName(); //   ivan.getAge(); //   ivan instanceof User; //    const text = JSON.stringify(ivan); //     const newIvan = JSON.parse(text); //   newIvan.getFullName(); // :  getFullName  newIvan.getAge(); // :  getAge  newIvan instanceof User; //     

ما هو سبب أخطاء إيفان الجديد؟ والحقيقة هي أن طريقة JSON.parse لا تلغي التسلسل إلى فئة المستخدم ، ولكن إلى فئة الكائن ، والتي ببساطة لا تحتوي على أساليب getFullName و getAge.

كيف تساعد مكتبتي في حل هذه المشكلة وإلغاء تسلسلها في المستخدم بدلاً من الكائن؟ يكفي تعديل الرمز قليلاً:

 import { jsonProperty, Serializable } from "ts-serializable"; export class User extends Serializable { @jsonProperty(String) public firstName: string = ""; @jsonProperty(String) public lastName: string = ""; @jsonProperty(Date) public birthDate: Date = new Date(); public getFullName(): string { return [this.firstName, this.lastName].join(' '); } public getAge(): number { return new Date().getFullYear() - this.birthDate.getFullYear(); } } const ivan = new User(); ivan.getFullName(); //   ivan.getAge(); //   ivan instanceof User; //    const text = JSON.stringify(ivan); //     const newIvan = new User().fromJson(JSON.parse(text)); //    User newIvan.getFullName(); //   newIvan.getAge(); //   newIvan instanceof User; //    

كل شيء بسيط للغاية. نحن نرث صفنا من فئة Serializable ، التي لديها طريقتان من Json لإلغاء التسلسل و to JSON للتسلسل ، ونعلق مصمم الديكورjsonProperty مع الخصائص التي يُسمح بقبولها من JSON. سيتم تجاهل البيانات غير الصالحة ، وسيتم إصدار تحذير لوحدة التحكم ، وستظل القيمة الافتراضية في الموقع.

هذا هو الأساس. الآن في المقدمة ، يمكنك إلغاء التسلسل والتسلسل بسهولة كما تفعل في C # و Java واللغات الأخرى. بناءً على سلوك Newtonsoft Json.NET.

التعليمات


لماذا ترث من Serializable؟

من أجل إضافة طريقتين من Json و toJSON إلى النموذج. يمكنك أن تفعل الشيء نفسه من خلال الديكور أو ترقيع القرد. لكن الميراث هو طريقة أكثر ملاءمة لطباعتها.

كيف يحدث التحقق من صحة البيانات

في الديكور ، يجب عليك تعيين مُنشئ لأنواع البيانات هذه المسموح بقبولها من JSON. ستقوم كائنات Boolean و String و Number بإرجاع boolean و string و number على التوالي. إذا كنت بحاجة إلى قبول مصفوفة ، فسيتم تأطير النوع بأقواس المصفوفة ، على سبيل المثالjsonProperty ([String]). إذا كان المنشئ موروثًا من فئة Serializable ، فسيتم أيضًا إلغاء تسلسله إلى الفئة ، إذا لم يكن كذلك ، فسيتم إرجاع الكائن.

كيفية التقاط أخطاء التحقق من الصحة؟

بشكل افتراضي ، تكتب المكتبة ببساطة تحذيرات إلى وحدة التحكم عن أخطاء التحقق من الصحة. لتجاوز هذا السلوك ، مثل إلقاء استثناءات أو تسجيل الدخول إلى الواجهة الخلفية ، يجب عليك تجاوز طريقة onWrongType للنموذج.

المكافأة 1. نسخة عميقة.


 const user1 = new Uesr(); const user2 = new User().fromJson(user1); //    

المكافأة 2. نماذج العرض البطيئة.


إذا كنت بحاجة إلى إنشاء نموذج ببيانات إضافية ، على سبيل المثال لطرق العرض ، ولكن لا تقبل الواجهة الخلفية ، يمكنك ببساطة توسيع النموذج بخصائص جديدة ووضع علامة على هذه الخصائص باستخدام الديكورjsonIgnore. وبعد ذلك لن يتم إجراء تسلسل لهذه الخصائص.

 import { jsonProperty, Serializable } from "ts-serializable"; export class User extends Serializable { @jsonProperty(String) public firstName: string = ""; @jsonIgnore() public isExpanded: boolean = false; } JSON.stringify(new User()); //  {"firstName":""} 

Source: https://habr.com/ru/post/ar428812/


All Articles