मैं जावास्क्रिप्ट में स्ट्रिंग्स से कक्षाएं बनाने की तलाश में हूं, जब तक कि मैं इस पर नहीं आया:

var instance = new window[classString]();

हालाँकि, यह टाइपस्क्रिप्ट में काम नहीं करता है, क्योंकि इसमें टाइप की जानकारी गायब है।

विवरण:

interface SomeInterface{
  structuredData: any;
}

class A implements SomeInterface {

}

मैं एक डेटाबेस में JSON क्रमबद्ध वर्ग की जानकारी संग्रहीत कर रहा हूँ। मान लें कि मेरे पास एक मॉडल वर्ग A है, उस वर्ग के गुणों को दृश्यपटल में JSON स्ट्रिंग के रूप में क्रमबद्ध किया जाता है और इस डेटा का प्रतिनिधित्व करने वाले वर्ग नाम के साथ डेटाबेस को भेजा जाता है, अर्थात डेटाबेस में एक class_type कॉलम होता है जिसमें वर्ग का नाम है। इस मामले में वह स्ट्रिंग 'ए' होगी। अब, मैं उस डेटा को अपने एप्लिकेशन में वापस लाना चाहता हूं और उस डेटा से गतिशील रूप से एक उदाहरण बनाना चाहता हूं।

अगर हम ऊपर पाए गए जावास्क्रिप्ट इंस्टेंटेशन कोड को देखते हैं, तो मुझे ऐसा कुछ करना अच्छा लगेगा:

let instance = new window['A']();
instance.structuredData = foo;

चूंकि उन वर्गों में सामान्य पैरामीटर होते हैं जो एक निश्चित इंटरफ़ेस का पालन करते हैं, इसलिए मैं उन नए तत्काल उदाहरणों को क्रमबद्ध डेटा असाइन करने में सक्षम हूं।

मैं Angular2/Webpack का उपयोग कर रहा हूं और वास्तव में किसी भी संकेत की सराहना करता हूं कि यह कैसे करना है।

ऊपर बताए गए कोड का उपयोग करते समय, मुझे निम्न कंपाइलर त्रुटि मिलती है:

एक अभिव्यक्ति के साथ 'नया' का उपयोग नहीं कर सकता जिसके प्रकार में कॉल या निर्माण हस्ताक्षर की कमी है।

अगर मैं उपयोग करके सख्त प्रकार की जाँच को रोकने की कोशिश करता हूँ

declare var window;

मुझे निम्नलिखित त्रुटि मिलती है:

विंडो ['क्लासस्ट्रिंग'] कंस्ट्रक्टर नहीं है

2
the_critic 25 फरवरी 2017, 19:20

2 जवाब

सबसे बढ़िया उत्तर

चूंकि Angular2 कुशलता से वेबपैक की भागीदारी को सारगर्भित करता है, मुझे नहीं पता कि मॉड्यूल कैसे लोड किए जाते हैं और विस्तार से संसाधित होते हैं। हालांकि, मेरा अनुमान (टिप्पणियों में उल्लिखित) यह है कि कक्षा खिड़की/वैश्विक स्थान में उपलब्ध नहीं है, इस प्रकार मैं एक समाधान के साथ आया हूं जो सही हो सकता है (कोशिश की और काम करता है, लेकिन यह सुनिश्चित नहीं है कि यह सही है या नहीं इस प्रकार की चीज़ करने का तरीका):

// first I require the module that is named in snake case with a .ts
// suffix based on the string that is stored in the database
// so if the stored string is SomeThing, we require the file
// called 'some_thing.ts'. Note: using lodash to generate that string
const dynModule = require('./' + _.snakeCase(classTypeString));

// next, we get the constructor by the class name from that module
// which is exactly the string that we stored in the db
const klass = dynModule[classTypeString];

// now we have the constructor function of the class and can
// instantiate a new class from that
let instance: SomeInterface = new klass();

instance.structuredData = foo;
2
the_critic 25 फरवरी 2017, 20:16

आप उन वर्गों को विंडो ऑब्जेक्ट के अंदर अपने आप रख सकते हैं, भले ही आप अन्य वर्गों के अंदर हों:

(window as any).example = class {}; // replace with you class
// and then later in code....
const classNameStr = 'example';
const init = new window[classNameStr]();

यदि आप विंडो ऑब्जेक्ट के अंदर लिखना पसंद नहीं करते हैं, तो आप उन्हें अपने कोड में कहीं किसी ऑब्जेक्ट/डिक्शनरी में स्टोर कर सकते हैं। या बस इवल का उपयोग करें (हालांकि इसका उपयोग करने के लिए यह एक अच्छा अभ्यास नहीं है):

eval(`new ${className}()`);
1
Marco Turi 27 मार्च 2017, 03:07