কয়েকটি ভিন্ন উপায় দেখানোর জন্য এগুলিতে কিছু দ্রুত শট sh এগুলি কোনওভাবেই "সম্পূর্ণ" নয় এবং অস্বীকৃতি হিসাবে, আমার মনে হয় না এটি এটি করা ভাল ধারণা। কোডটি খুব বেশি পরিষ্কার নয় যেহেতু আমি কেবল এটির সাথে দ্রুত টাইপ করেছি।
এছাড়াও একটি নোট হিসাবে: অবশ্যই deserializable শ্রেণীর ডিফল্ট নির্মাতাদের যেমন প্রয়োজন হয় অন্য সমস্ত ভাষায় যেখানে আমি যে কোনও ধরণের deserialization সম্পর্কে সচেতন। অবশ্যই জাভাস্ক্রিপ্ট অভিযোগ করবে না যদি আপনি কোনও যুক্তি ছাড়াই অ-ডিফল্ট নির্মাতাকে কল করেন তবে ক্লাসটি তার জন্য আরও ভাল প্রস্তুত থাকুন (প্লাস, এটি আসলে "টাইপস্ক্রিপি উপায়" হবে না)।
বিকল্প # 1: কোনও রান-টাইম তথ্য নেই
এই পদ্ধতির সমস্যাটি বেশিরভাগ ক্ষেত্রে যে কোনও সদস্যের নাম অবশ্যই তার শ্রেণীর সাথে মেলে। যা স্বয়ংক্রিয়ভাবে আপনাকে প্রতি ক্লাসে একই ধরণের এক সদস্যের মধ্যে সীমাবদ্ধ করে দেয় এবং ভাল অনুশীলনের বেশ কয়েকটি নিয়ম ভঙ্গ করে। আমি এর বিরুদ্ধে দৃ strongly়ভাবে পরামর্শ দিচ্ছি, তবে কেবল এটি এখানে তালিকাবদ্ধ করুন কারণ যখন আমি এই উত্তরটি লিখি তখন এটিই প্রথম "খসড়া" ছিল (যার কারণেই নামগুলি "ফু" ইত্যাদি)।
module Environment {
export class Sub {
id: number;
}
export class Foo {
baz: number;
Sub: Sub;
}
}
function deserialize(json, environment, clazz) {
var instance = new clazz();
for(var prop in json) {
if(!json.hasOwnProperty(prop)) {
continue;
}
if(typeof json[prop] === 'object') {
instance[prop] = deserialize(json[prop], environment, environment[prop]);
} else {
instance[prop] = json[prop];
}
}
return instance;
}
var json = {
baz: 42,
Sub: {
id: 1337
}
};
var instance = deserialize(json, Environment, Environment.Foo);
console.log(instance);
বিকল্প # 2: নাম সম্পত্তি
বিকল্প # 1-এ সমস্যা থেকে মুক্তি পাওয়ার জন্য, আমাদের JSON অবজেক্টে নোড কি টাইপ করা উচিত তার কিছু প্রকারের তথ্য থাকতে হবে। সমস্যাটি হ'ল টাইপস্ক্রিপ্টে, এই জিনিসগুলি সংকলন-সময় কনস্ট্রাক্টস এবং রানটাইমের সময় আমাদের এগুলি প্রয়োজন - তবে রানটাইম অবজেক্টগুলি কেবল সেগুলি সেট না হওয়া পর্যন্ত তাদের বৈশিষ্ট্য সম্পর্কে কোনও সচেতনতা রাখে না।
এটি করার একটি উপায় হ'ল ক্লাসগুলি তাদের নাম সম্পর্কে সচেতন করা। যদিও আপনার JSON এ এই সম্পত্তি প্রয়োজন। প্রকৃতপক্ষে, আপনার কেবল এটি জাসনে দরকার:
module Environment {
export class Member {
private __name__ = "Member";
id: number;
}
export class ExampleClass {
private __name__ = "ExampleClass";
mainId: number;
firstMember: Member;
secondMember: Member;
}
}
function deserialize(json, environment) {
var instance = new environment[json.__name__]();
for(var prop in json) {
if(!json.hasOwnProperty(prop)) {
continue;
}
if(typeof json[prop] === 'object') {
instance[prop] = deserialize(json[prop], environment);
} else {
instance[prop] = json[prop];
}
}
return instance;
}
var json = {
__name__: "ExampleClass",
mainId: 42,
firstMember: {
__name__: "Member",
id: 1337
},
secondMember: {
__name__: "Member",
id: -1
}
};
var instance = deserialize(json, Environment);
console.log(instance);
বিকল্প # 3: স্পষ্টভাবে সদস্যের প্রকারের উল্লেখ করে
উপরে উল্লিখিত হিসাবে, শ্রেণীর সদস্যদের প্রকারের তথ্য রানটাইমে পাওয়া যায় না - এটি যদি না আমরা তা উপলব্ধ না করি। আমাদের কেবল অ-আদিম সদস্যদের জন্য এটি করা দরকার এবং আমরা যেতে ভাল:
interface Deserializable {
getTypes(): Object;
}
class Member implements Deserializable {
id: number;
getTypes() {
// since the only member, id, is primitive, we don't need to
// return anything here
return {};
}
}
class ExampleClass implements Deserializable {
mainId: number;
firstMember: Member;
secondMember: Member;
getTypes() {
return {
// this is the duplication so that we have
// run-time type information :/
firstMember: Member,
secondMember: Member
};
}
}
function deserialize(json, clazz) {
var instance = new clazz(),
types = instance.getTypes();
for(var prop in json) {
if(!json.hasOwnProperty(prop)) {
continue;
}
if(typeof json[prop] === 'object') {
instance[prop] = deserialize(json[prop], types[prop]);
} else {
instance[prop] = json[prop];
}
}
return instance;
}
var json = {
mainId: 42,
firstMember: {
id: 1337
},
secondMember: {
id: -1
}
};
var instance = deserialize(json, ExampleClass);
console.log(instance);
বিকল্প # 4: ভার্বোজ, তবে ঝরঝরে
01/03/2016 আপডেট করুন: যেমন @ গেমএলচেমিস্ট মন্তব্যগুলিতে ( ধারণা , বাস্তবায়ন ) ইঙ্গিত করেছেন, টাইপস্ক্রিপ্ট ১.7 অনুসারে, নীচে বর্ণিত সমাধানটি শ্রেণি / সম্পত্তি সাজসজ্জার ব্যবহার করে আরও ভালভাবে লেখা যেতে পারে।
সিরিয়ালাইজেশন সর্বদা একটি সমস্যা এবং আমার মতে, সবচেয়ে ভাল উপায় একটি উপায় যা কেবল সবচেয়ে কম নয়। সমস্ত অপশনগুলির মধ্যে, আমি এটিই পছন্দ করব কারণ শ্রেণীর লেখকের ডিসরিয়ালাইজড অবজেক্টগুলির রাজ্যের সম্পূর্ণ নিয়ন্ত্রণ রয়েছে। যদি আমার অনুমান করতে হয় তবে আমি বলব যে তাড়াতাড়ি বা পরে অন্যান্য সমস্ত অপশন আপনাকে সমস্যায় ফেলবে (যতক্ষণ না জাভাস্ক্রিপ্ট এগুলি মোকাবেলার জন্য একটি স্থানীয় উপায় নিয়ে আসে)।
সত্যই, নিম্নলিখিত উদাহরণটি নমনীয়তা ন্যায়বিচার করে না। এটি সত্যই ক্লাসের কাঠামোটি অনুলিপি করে। এখানে আপনার যে পার্থক্যটি মনে রাখতে হবে তা হ'ল ক্লাসটির যে কোনও ধরণের জেএসওএন ব্যবহার করার সম্পূর্ণ নিয়ন্ত্রণ রয়েছে যা এটি পুরো বর্গের অবস্থা নিয়ন্ত্রণ করতে চায় (আপনি জিনিসগুলি গণনা করতে পারেন))
interface Serializable<T> {
deserialize(input: Object): T;
}
class Member implements Serializable<Member> {
id: number;
deserialize(input) {
this.id = input.id;
return this;
}
}
class ExampleClass implements Serializable<ExampleClass> {
mainId: number;
firstMember: Member;
secondMember: Member;
deserialize(input) {
this.mainId = input.mainId;
this.firstMember = new Member().deserialize(input.firstMember);
this.secondMember = new Member().deserialize(input.secondMember);
return this;
}
}
var json = {
mainId: 42,
firstMember: {
id: 1337
},
secondMember: {
id: -1
}
};
var instance = new ExampleClass().deserialize(json);
console.log(instance);