2009-07-11 15 views
27

व्याख्या करने के लिए सबसे अच्छा तरीका है उदाहरण तो साथ है:एमवीवीएम: क्या एक वीएम ऑब्जेक्ट सीधे एम ऑब्जेक्ट का खुलासा कर सकता है, या केवल एम के गेटर्स को सौंपने वाले गेटर्स के माध्यम से?

इस मॉडल

public class Person 
{ 
    public int age; 
    public string name; 
} 

इस दृश्य मॉडल है है

public class PersonVM 
{  
} 

मेरे सवाल यह है:
वी एम का पर्दाफाश करना चाहिए डेटा टेम्पलेट के लिए व्यक्ति या मॉडल गुणों को अपने गुणों के साथ encapsulate?

+0

इन साधारण परिदृश्यों में व्यूमोडेल होने का शून्य लाभ है। यदि आप कहते हैं कि एक पूर्ववत फ़ंक्शन इत्यादि को कार्यान्वित करना चाहते हैं तो वह तर्क VM में जाएगा और आप मॉडल गुणों को लपेटेंगे। – rolls

उत्तर

18

दृश्य मॉडल को अपनी संपत्ति घोषित करनी चाहिए और दृश्य से मॉडल के विनिर्देशों को छिपाना चाहिए। यह आपको सबसे लचीलापन देता है, और मॉडल-प्रकार के मुद्दों को मॉडल कक्षाओं में लीक करने से रोकने में मदद करता है। आमतौर पर आपके व्यू मॉडल क्लास प्रतिनिधिमंडल द्वारा मॉडल को समाहित करते हैं। उदाहरण के लिए,

class PersonModel { 
    public string Name { get; set; } 
} 

class PersonViewModel { 
    private PersonModel Person { get; set;} 
    public string Name { get { return this.Person.Name; } } 
    public bool IsSelected { get; set; } // example of state exposed by view model 

    public PersonViewModel(PersonModel person) { 
     this.Person = person; 
    } 
} 

याद रखें: मॉडल है कि यह लेने वाली दृश्य मॉडल के बारे में कुछ भी पता नहीं करना चाहिए, और देखने मॉडल दृश्य है कि यह लेने के बारे में कुछ भी पता नहीं करना चाहिए। दृश्य पृष्ठभूमि में छिपे हुए मॉडल के बारे में कुछ नहीं जानना चाहिए। इस प्रकार, दृश्य मॉडल में गुणों के पीछे मॉडल को समाहित करें।

+0

PersonViewModel क्लास में पर्सनल मॉडेल पैरामीटर के साथ एक सार्वजनिक कन्स्ट्रक्टर है। तो दृश्य को मॉडल मॉडल को तुरंत चालू करने के लिए मॉडल को जानना चाहिए ... यह mvvm नहीं है। कन्स्ट्रक्टर आंतरिक होना चाहिए या स्ट्रिंग या जेनरेट करने के लिए जो कुछ भी सामान्य पैरामीटर लेना चाहिए। –

+0

आइए कहें कि आप मॉडल में (यूआई के माध्यम से) एक मान बदलते हैं। नतीजतन मॉडल फिर कुछ अन्य मूल्यों को भी बदलता है (जैसा कि वे इस पर निर्भर करते हैं)। क्या आप एक ऑनप्रॉपर्टी चेंजड हैंडलर को आग लगाएंगे और वीएम को अपनी संपत्ति अपडेट करेंगे? मैंने यही किया है और यह अच्छी तरह से काम करता है, लेकिन मैं इसके लिए नया हूं और इसके खराब अभ्यास के बारे में अनिश्चित हूं। – rolls

+0

उपर्युक्त टिप्पणी दें। यह आलेख ठीक से लागू होता है जो मैंने किया है। https://msdn.microsoft.com/en-us/magazine/ff798279.aspx – rolls

31

उस प्रश्न के बारे में कोई आम सहमति नहीं है। उदाहरण के लिए यह वार्ड बेल here द्वारा तैयार MVVM के बारे में खुले प्रश्न में से एक था:

वी एम वी एक unwrapped एम ऑब्जेक्ट (उदा, कच्चे कर्मचारी) की पेशकश करने की अनुमति दी है? या एम-ऑब्जेक्ट की गुणों (यदि इसे गुणों की भी अनुमति है) को विशेष रूप से वीएम रैपर की सतह के माध्यम से उजागर किया जाना चाहिए?

सीधे वी एम में मॉडल उजागर नहीं की प्रिंसिपल लाभ हैं:

  • आप इसे एक "स्टेरॉयड पर कनवर्टर" के रूप में, एक सुविधाजनक तरीके से देखने के लिए उपयोग कर सकते हैं मॉडल मूल्यों formating

  • आप अन्य यूजर इंटरफेस से संबंधित funcionality, data validation messages, undo redo, जैसे इंजेक्षन कर सकते हैं ..

विपक्ष हैं:

  • आप कोड का एक बहुत viewmodel में सभी मॉडलों के गुण को बेनकाब करने के नकल करना होगा।

  • यदि आप व्यूमोडेल प्रॉपर्टी पर दृश्य नियंत्रण को बाध्य करते हैं, तो आप व्यूमोडेल से संपत्ति को बदल देंगे। लेकिन क्या होता है यदि मॉडलों की संपत्ति अन्य स्रोत से बदलती है जो व्यूमोडेल सेटर से अलग है? फिर इसे व्यूमोडेल को सूचित करना होगा ताकि आप 2 ऑनप्रॉपर्टी चेंज, मॉडल में से एक और व्यूमोडेल में से एक को समाप्त कर सकें ... काफी जटिल!

तो मेरे लिए सही उत्तर है: यह आपकी आवश्यकताओं पर निर्भर करता है।

+1

विपक्ष के लिए एक आसान समाधान है, दृश्य मॉडल को प्रॉक्सी बनाएं, सभी कार्यक्षमताओं के साथ आप –

+0

जोड़ना चाहते हैं यह एक महान उदाहरण है मॉडल को "लपेटें" के लिए एक अच्छा समय और फिर शीर्ष पर अधिक कार्यक्षमता इंजेक्ट करें। – rolls

5

किसी भी मॉडल के लिए व्यूमोडेल होने से उससे भी बदतर हो सकता है। क्या होगा यदि आपके पास मॉडल की पदानुक्रमिक संरचना है, या यहां तक ​​कि एक साधारण संग्रह भी है? उस स्थिति में आपको सभी मॉडलों के माध्यम से फिर से शुरू करना होगा और प्रति-मॉडल उदाहरण देखें, और अधिसूचना-परिवर्तन घटनाओं या अन्य घटनाओं को पंजीकृत करने के लिए भी। आईएमएचओ, यह पूरी तरह से पागल है, और अनुचित है। जैसा कि डेनसी ने कहा था, आप बहुत सारे कोड और एक बड़ा सिरदर्द खत्म कर देंगे।

+1

मैं आपसे सहमत हूं, अब क्या है? – Shimmy

+0

यह एक मौजूदा मॉडल पेड़ को एक वीएम में लपेटने के लिए अपेक्षाकृत सीधे आगे की प्रक्रिया है। एक उपयोगिता बनाएं जो इसे करता है, या बेहतर अभी तक इसे अपने स्वयं के बेस वीएम कक्षा में बनाएं। हां, वीएम स्थापित करने और उन्हें अपने विचारों में जोड़ने में शामिल कुछ अतिरिक्त जटिलता है, लेकिन यह इसके लायक है। नतीजा दृश्य पेड़ के प्रत्येक स्तर पर स्मार्ट कोड तत्व है। ऑपरेशन को संभालने के लिए किसी को ढूंढने के लिए दृश्य पेड़ को और खोजना नहीं। –

+1

मुझे एमवीवीएम तक दृश्य हिट परीक्षण के बिना अलग-अलग ListBoxItems पर जटिल संचालन से निपटने का कोई अच्छा तरीका कभी नहीं मिला है। एक बार जब आप अपना वीएम पदानुक्रम बनाते हैं और प्रत्येक वीएम को उचित संदर्भ देते हैं, तो ListBoxItems में अपने स्वयं के जटिल संचालन करने के लिए आवश्यक सब कुछ है। –

5

यह करने के लिए एक दिलचस्प समाधान MSDN मात्रा में रॉबर्ट McCarter द्वारा प्रस्तावित किया गया था 25.

http://msdn.microsoft.com/en-us/magazine/ff798279.aspx

वह एक गतिशील दृश्य मॉडल का उपयोग करता है, जबकि मॉडल के सभी प्रॉक्सी से परहेज मॉडल के शीर्ष पर एक परत प्रदान करने के गुण।

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

+0

या दोनों दुनिया के सर्वश्रेष्ठ का उपयोग करें ... एक गतिशील आधार परिभाषित करें मॉडल वर्ग और एक गैर गतिशील आधार देखें मॉडल देखें। अन्य प्रदर्शन के लिए उच्च प्रदर्शन दृश्य मॉडल और गतिशील बेस क्लास के लिए गैर-गतिशील का उपयोग करें। –

+0

याद रखें कि डीएलआर सिल्वरलाइट में समर्थित नहीं है: '( मुझे प्रॉक्सी गुणों से भी नफरत है। – Shimmy

+0

@Shimmy: यह आश्चर्य की बात नहीं है। सिल्वरलाइट अभी भी बहुत सी WPF की महानता खो रहा है। –