2013-05-02 4 views
5

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

  • मैं स्ट्रिंग नामों का उपयोग नहीं कर सकता क्योंकि स्ट्रिंग नाम minifier को कॉल के बीच तय नहीं किए गए हैं। (यह पूरी तरह से धारावाहिकता तोड़ देगा)

उत्तर

8

आप MirrorSystem.getName(symbol)

तो एक गतिशील वर्ग के साथ मूल नाम का उपयोग कर सकते ऐसा लग सकता है:

import 'dart:mirrors'; 

class A { 
    final _properties = new Map<String, Object>(); 

    noSuchMethod(Invocation invocation) { 
    if (invocation.isAccessor) { 
     final realName = MirrorSystem.getName(invocation.memberName); 
     if (invocation.isSetter) { 
     // for setter realname looks like "prop=" so we remove the "=" 
     final name = realName.substring(0, realName.length - 1); 
     _properties[name] = invocation.positionalArguments.first; 
     return; 
     } else { 
     return _properties[realName]; 
     } 
    } 
    return super.noSuchMethod(invocation); 
    } 
} 

main() { 
    final a = new A(); 
    a.i = 151; 
    print(a.i); // print 151 
    a.someMethod(); // throws 
} 
+0

असली नाम प्रारूप कुछ है जो काफी स्थिर है या क्या मुझे हर बार डार्ट का नया संस्करण आने पर मेरा कोड अपडेट करने की चिंता करने की ज़रूरत है? – jz87

+0

मुझे वास्तव में पता नहीं है कि प्रारूप निर्दिष्ट है या नहीं [भाषा विनिर्देश] (https://www.dartlang.org/docs/spec/latest/dart-language-specification.html) _setter ' v = '_। तो मैं कहूंगा कि यह लगभग परिभाषित है। मेलिंग सूची या किसी अन्य SO प्रश्न में पूछने के लिए स्वतंत्र महसूस करें :) –

0

यदि आपको केवल "गतिशील गुण" की आवश्यकता है, तो यह मानचित्र में कुंजी के रूप में प्रतीकों का उपयोग करने के लिए पर्याप्त होना चाहिए। यदि आप उस मानचित्र को क्रमबद्ध करना चाहते हैं, तो आपको मूल स्ट्रिंग नामों का ट्रैक रखने और क्रमबद्ध करने के लिए उन लोगों का उपयोग करने की आवश्यकता है। जब deserializing, आप उन स्ट्रिंग्स से नए प्रतीक बनाना होगा।

ध्यान दें कि इन सभी परिदृश्यों (और मूल रूप से new Symbol में शामिल सभी चीज़ों के लिए) को संकलित करने वाले को मूल नामों के मानचित्रण बनाने और प्रोग्राम में इस मैपिंग को रखने की आवश्यकता होती है, जो निश्चित रूप से इसे बड़ा बनाता है।

+0

हाँ समस्या यह है कि मैं मूल स्ट्रिंग नामों तक कैसे पहुंच प्राप्त करूं? NoSuchMethod मूल स्ट्रिंग का पर्दाफाश नहीं करता है, जो आप आमंत्रण ऑब्जेक्ट से प्राप्त करते हैं वह प्रतीक है। – jz87

+0

ठीक है, जब आप चीजों को मानचित्र में डाल रहे हैं तो आपको मूल नाम रिकॉर्ड करना होगा। संपादित करें: ओह हाँ, स्वीकृत उत्तर सही है, पीछे की ओर मैपिंग है। इसके बारे में याद नहीं आया। – Ladicek

0

आप कुछ इस तरह कर सकता है:

import 'dart:json' as json; 

main() { 
    var t = new Thingy(); 
    print(t.bob()); 
    print(t.jim()); 
    print(json.stringify(t)); 
} 

class Thingy { 
    Thingy() { 
     _map[const Symbol('bob')] = "blah"; 
     _map[const Symbol('jim')] = "oi"; 
    } 

    final Map<Symbol, String> _map = new Map<Symbol, String>(); 

    noSuchMethod(Invocation invocation) { 
     return _map[invocation.memberName]; 
    } 

    toJson() => { 
     'bob': _map[const Symbol('bob')], 
     'jim': _map[const Symbol('jim')]}; 
} 

अपडेट - गतिशील उदाहरण:

import 'dart:json' as json; 

main() { 
    var t = new Thingy(); 
    t.add('bob', 'blah'); 
    t.add('jim', 42); 
    print(t.bob()); 
    print(t.jim()); 
    print(json.stringify(t)); 
} 

class Thingy { 
    final Map<Symbol, String> _keys = new Map<Symbol, String>(); 
    final Map<Symbol, dynamic> _values = new Map<Symbol, dynamic>(); 

    add(String key, dynamic value) { 
     _keys[new Symbol(key)] = key; 
     _values[new Symbol(key)] = value; 
    } 

    noSuchMethod(Invocation invocation) { 
     return _values[invocation.memberName]; 
    } 

    toJson() { 
     var map = new Map<String, dynamic>(); 
     _keys.forEach((symbol, name) => map[name] = _values[symbol]); 
     return map; 
    } 
} 
+0

जो मैं वास्तव में चाहता हूं वह एक्सपोन्ड ऑब्जेक्ट जैसा कुछ है। मैं निश्चित गुणों के साथ थिंगी को परिभाषित करने में सक्षम होना चाहता हूं + अतिरिक्त गुण जिन्हें रनटाइम पर जोड़ा जा सकता है। – jz87

+0

मैंने एक गतिशील उदाहरण जोड़ा है - क्या आपका मतलब है? इसका लाभ यह है कि आपको प्रतिबिंब का उपयोग करने की आवश्यकता नहीं है, जिसका अर्थ यह है कि यह dart2js के साथ बेहतर काम करेगा। जोड़ों का उपयोग करने के बजाय सेटर्स को संभालना बहुत आसान होना चाहिए - आप उपरोक्त एलेक्सड्रेस के उदाहरण में कुछ कोड का उपयोग कर सकते हैं। –

+0

ओह - आप स्पष्ट रूप से दर्पण के बिना सेटर्स को संभाल नहीं सकते हैं। गेटनाम()। –

संबंधित मुद्दे