MVC में, क्या मॉडल से बुनियादी डेटा पुनर्प्राप्ति को दृश्य में किया जा सकता है?


10

The स्किनी कंट्रोलर्स, फैट मॉडल्स ’ की अवधारणा और सामान्य स्वीकृति को देखते हुए कि आउटपुट के लिए डेटा की आवश्यकता होने पर व्यू सीधे मॉडल पर कॉल कर सकते हैं, क्या किसी को व्यूज और कंट्रोलर के भीतर अनुरोधों के parts प्राप्त और प्रदर्शन’ के हिस्सों को संभालने पर विचार करना चाहिए? उदाहरण के लिए (कोड को सामान्य रखने का प्रयास):

नियंत्रक

<?php

class Invoice extends Base_Controller {

    /**
     * Get all the invoices for this month
     */

    public function current_month() {

        // as there's no user input let's keep the controller very skinny,
        // DON'T get data from the Model here, just load the view

        $this->load->view('invoice/current_month');

    }

}

राय

<?php

// directly retrieve current month invoices here

$invoices = $this->invoice_model->get_current_month();

// get some other display-only data, e.g. a list of users for a separate list somewhere on the page

$users = $this->user_model->get_users();

?>

<h1>This month's invoices</h1>

<ul>
<?php foreach ($invoices as $invoice) { ?>

<li><?php echo $invoice['ref']; ?></li>

<?php } ?>
</ul>

मेरे लिए, यह उन मामलों में कम से कम कुछ समझ में आता है जहां अनुरोध अनिवार्य रूप से केवल एक दृश्य है। डेटा को देखने के लिए नियंत्रक को क्यों इकट्ठा करना चाहिए और पास करना चाहिए, जब यह केवल इसे स्वयं पुनः प्राप्त कर सकता है? यह कंट्रोलर को शुद्ध रूप से 'एप्लीकेशन लेवल' प्रोसेसिंग के लिए खुला छोड़ देता है (जैसे GET / POST रिक्वेस्ट को हैंडल करना, एक्सेस राइट्स और परमिशन आदि को मैनेज करना) और साथ ही मॉडल्स को दोबारा और बाकी सभी अच्छे सामान को रखना।

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

क्या यह एमवीसी एप्लिकेशन विकसित करने का एक वैध तरीका है? या क्या मुझे नियंत्रक द्वारा निभाई जाने वाली भूमिका का एक महत्वपूर्ण हिस्सा दिखाई दे रहा है?

जवाबों:


17

हां, यह तकनीकी रूप से किया जा सकता है। नहीं, ऐसा नहीं किया जाना चाहिए। और हाँ, आप इस बात से चूक रहे हैं कि नियंत्रक क्या है।

नियंत्रक मॉडल से दृश्य को डिकूप करने के लिए है। डिकॉप्लिंग फायदेमंद है क्योंकि आपको व्यू को लगभग फेंक-दूर कोड के रूप में देखना चाहिए। जैसे ही आपकी UI तकनीक बदलती है, आप एक नया दृश्य बनाने में आवश्यक पुनर्प्राप्ति को कम करना चाहते हैं। कंट्रोलर उस डिकूप्लिंग को सक्षम करता है और आपके कोड के लिए एक जगह प्रदान करता है जो UI तकनीकों के माध्यम से लाइव होगा।

यदि आप अपने मॉडल को जोड़ना या बदलना चाहते हैं तो यह उल्टा काम करता है। अपस्ट्रीम परिवर्तन के सभी नियंत्रक के भीतर निहित होंगे और आपके दृश्य अकेले रह जाएंगे।

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


1
शानदार जवाब, धन्यवाद। अपने 'आगे देख' परिदृश्य को थोड़ा बढ़ाकर; यदि किसी पृष्ठ पर सामान्य जानकारी है जो कि अनुरोध किए गए के लिए अलग है (जैसे उपयोगकर्ता एक विशिष्ट उत्पाद देख रहा है, तो 'नवीनतम विशेष प्रस्तावों की एक सामान्य सूची' इस तरफ दिखाई जाती है) कॉल कैसे / कहां से किया जाना चाहिए offers_model->get_latest()? नियंत्रक में हर विधि में इसे जोड़ना (जैसा कि मैंने पहले मूर्खतापूर्ण प्रयास किया है) लगता है कि ओवरकिल और विशिष्ट रूप से अन-डीआरवाई।
एडम वेस्टब्रुक

2
@AdamWestbrook MVVM पर एक नज़र डालें। उस का ViewModel भाग इस विशिष्ट समस्या को हल कर सकता है। आप offers_model->get_latest()एक ProductViewModelबेस क्लास या कुछ इसी तरह से जोड़ सकते हैं ।
ज़ाचरी येट्स

1
महान, मैं निश्चित रूप से एमवीवीएम में फिर से शुक्रिया अदा करूंगा।
एडम वेस्टब्रुक

बहुत अच्छा जवाब, रक्षात्मक रूप से इस तारांकित को रखेंगे। व्यक्तिगत रूप से मैं MVVM :) का एक बड़ा प्रशंसक हूं
बेंजामिन ग्रुएनबाउम

@BenjaminGruenbaum क्या आप PHP में MVVM का उपयोग कर रहे हैं? यदि ऐसा है तो क्या आप इसके लिए किसी विशेष ढांचे का उपयोग कर रहे हैं?
एडम वेस्टब्रुक

6

'पतली नियंत्रकों, वसा मॉडल' की अवधारणा को देखते हुए और सामान्य स्वीकृति कि दृश्य सीधे मॉडल पर कॉल कर सकते हैं जब आउटपुट के लिए डेटा की आवश्यकता होती है

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

क्या दृश्य के भीतर अनुरोधों के 'प्राप्त और प्रदर्शन' भागों को संभालने पर विचार करना चाहिए और नियंत्रक पर नहीं?

यह मूल रूप से नियंत्रक को मिटा देता है, और उन्हें होने के बिंदु को हरा देता है।

डेटा को देखने के लिए नियंत्रक को क्यों इकट्ठा करना चाहिए और पास करना चाहिए, जब यह केवल इसे स्वयं पुनः प्राप्त कर सकता है?

नियंत्रक डेटा एकत्र नहीं करता है। मॉडल डेटा का संग्रह करता है। यदि यह डेटा दृश्य में पास किया जाना चाहिए तो नियंत्रक तय करता है । दृश्य केवल डेटा की प्रस्तुति करता है।

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

नहीं।

नियंत्रक जाँच करता है कि यदि POSTed डेटा वैध है, तो वह इस डेटा को मॉडल के विकल्प के रूप में पास करता है, जो तब डेटा स्रोत को क्वेरी करेगा और डेटा को लौटाएगा, और नियंत्रक उस दृश्य को पास करता है।

क्या यह एमवीसी एप्लिकेशन विकसित करने का एक वैध तरीका है? या क्या मुझे नियंत्रक द्वारा निभाई जाने वाली भूमिका का एक महत्वपूर्ण हिस्सा दिखाई दे रहा है?

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

देखने का बिंदु HTML और डेटा स्रोत की प्रस्तुति के बीच संरचना और निर्भरता को कम करना है। जबकि यह मुश्किल हो सकता है। दृश्य हमेशा एक मॉडल से सीधे आने वाले डेटा को प्रस्तुत नहीं करते हैं। नियंत्रक अक्सर अतिरिक्त डेटा जोड़ता है जो प्रासंगिक है।

मुझे यकीन है कि MVC पर बहुत सारे ट्यूटोरियल हैं। मैं उनमें से कुछ को पढ़ने की सलाह दूंगा।


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

जब आप कई नियंत्रकों द्वारा उपयोग किए जाने वाले मॉडल प्राप्त करना शुरू करते हैं। उनके मोटा होने की आवश्यकता बहुत स्पष्ट हो जाती है। जब View में बहुत अधिक PHP सम्‍मिलित होने लगती है तो आप जानते हैं कि आपका नियंत्रक पतला होना है। जब आपके नियंत्रक बहुत मोटे होते हैं। अन्य नियंत्रकों को उसी तरह से संचालित करना मुश्किल है (उदाहरण के लिए, एपीआई सेवा को जोड़ना)।
रिएक्टगुलर

3

मुझे आपका प्रश्न बहुत दिलचस्प लगा क्योंकि मैं हाल ही में पायथन सीखते समय इसी मुद्दे पर आया था।

जबकि दिए गए उत्तर एक ठोस तर्क देते हैं, मुझे लगा कि मैं एक और राय जोड़ूंगा, जिसमें मैं देख रहा हूं जिसमें नियंत्रक के माध्यम से देखे बिना मॉडल की स्थिति मिलती है।

MVC

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

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

स्मॉलटाकल -80 में एप्लिकेशन प्रोग्रामिंग में: मॉडल-व्यू-कंट्रोलर (एमवीसी) का उपयोग कैसे करें [बुर्बेक92], स्टीव बर्बेक ने एमवीसी के दो रूपों का वर्णन किया है: एक निष्क्रिय मॉडल और एक सक्रिय मॉडल।

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

एमवीसी - निष्क्रिय मॉडल

मैं यह कहने की स्थिति में नहीं हूं कि कौन सी राय "सही" है, और ईमानदार होने के लिए, मैं यहां और जुड़े लेख पढ़ने के बाद थोड़ा और भ्रमित हूं।

लेख का पूरा पाठ यहाँ


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

लिंक के लिए धन्यवाद, मुझे पता था कि मैं यह सोचने में पागल नहीं था! यह अनिवार्य रूप से है जो मैं दूर जा रहा था इससे पहले कि मैं इस विचार को बहुत दूर ले गया, जब तक कि मॉडल किसी भी चीज पर निर्भर नहीं है, इससे क्या फर्क पड़ता है कि यह कैसे / कहाँ पहुँचा जाता है? मैंने यह तय नहीं किया है कि मैं अपने अगले विकास के लिए क्या दृष्टिकोण अपनाने जा रहा हूं, लेकिन यह निश्चित रूप से मदद करता है।
एडम वेस्टब्रुक

1

विचार करने के लिए एक और बात यह है कि आप इसे देखने के लिए ऑटोलॉइड user_modelऔर invoice_modelदृश्य को एक्सेस करने की अनुमति देते हैं। इसके लिए मज़बूती से काम करने के लिए, आप शायद अपने सभी मॉडलों को ऑटोलॉड करें (क्योंकि $this->load->model()सिर्फ एक दृश्य में गलत दिखता है, नहीं ...)

ऐसा करना अनावश्यक रूप से आपके ढेर को एक सामान की लोडिंग से फुला देता है जो शायद कभी उपयोग नहीं किया जा सकता है। एक से अधिक मॉडल होने का कारण यह है कि आप संबंधित तर्क को एनकैप्सुलेट कर सकते हैं और केवल उसी चीज़ को लोड कर सकते हैं जो आपको दिए गए कार्य के लिए चाहिए।

यह CodeIgniter की तरह दिखता है। मैंने बहुत सी सीआई विकास किया है और मैं व्यक्तिगत अनुभव से साझा कर सकता हूं कि आप वास्तव में ऑटोलैड से अधिक नहीं चाहते हैं जो आपके पास वास्तव में है। $this->output->enable_profiler(TRUE);एक कंट्रोलर के कंस्ट्रक्टर में जोड़ने की कोशिश करें और ऑटोलॉड्स (जैसे सहायकों सहित database) के साथ फिडेल करें : आपको संभवतः लोड और निष्पादन समय में महत्वपूर्ण बदलाव दिखाई देगा, लेकिन विशेष रूप से मेमोरी आवंटन में।


1
अच्छे अंक, आप सही हैं यह सीआई पर आधारित है, हालांकि मैंने स्पष्टता के लिए कुछ विशिष्ट वाक्यविन्यास हटा दिए हैं। मैं काफी हद तक समय और DRY कारणों के लिए बहुत कुछ 'ऑटोलोडिंग' की आदत में पड़ गया हूं, ऐसा लगता है कि load->modelअधिकांश नियंत्रकों और तरीकों में बहुत कुछ पागल है । एक उचित ऑटोलॉड फंक्शन का उपयोग न करना एक ऐसी चीज है जिसे मैं CI के बैकवर्ड कम्पेटिबिलिटी के बारे में नापसंद करता हूं, लेकिन यह एक पूरी अन्य चर्चा है ...
एडम वेस्टब्रुक

0

संक्षिप्त उत्तर यह है कि आपके कोड नमूने का रूप भ्रामक रूप से सहज है। ऐसा लगता है कि यह जाने के लिए "मन पर आसान" रास्ता है।


समस्या # 1

आपकी Modelऔर Viewवस्तुओं को कसकर युग्मित किया जाएगा।

यदि आपको कभी भी तरीकों को जोड़ना या हटाना है Model, तो आपको Viewतदनुसार परिवर्तन करना पड़ सकता है ।

मूल रूप से, MVC कमांड और ऑब्जर्वर पैटर्न से लिया गया है। तुम एक चाहते हैं स्वतंत्र 'मॉडल' है कि एक के माध्यम से छेड़छाड़ इंटरफ़ेस / एपीआई कि Controller(यानी प्रतिनिधिमंडल) में हुक कर सकते हैं।

अक्सर, इस का मतलब है इंजेक्शन लगाने Model और Viewएक में उदाहरणों Controllerऔर उन्हें कहा की एक गुण के रूप में भंडारण Controller। फिर, Controllerकार्य क्षेत्र के रूप में (यानी एक कमांड) की एक विधि का उपयोग करके , से डेटा पास View करें Model ( `मॉडल के बाद आवेदन स्थिति को अपडेट करने के बाद )।

डेटा पास करना (सरणियाँ, पुनरावृत्त वस्तुएं, जो कुछ भी) के बीच युग्मन रहता है Modelऔर Viewउदाहरण ढीले होते हैं । यदि आप Modelउदाहरण में इंजेक्ट करते हैं View, तो समस्या # 1 ऊपर देखें।

याद रखें, Viewsप्रतिनिधित्व स्थिति हस्तांतरण पद्धति (REST) ​​के बाद HTML, JSON, टेक्स्ट, XML, HTTP हेडर, YAML या लगभग कुछ भी हो सकता है

इस प्रकार, यह समझने की कुंजी है कि रिश्ते को कैसे प्रबंधित किया जाए Modelऔर Viewsयह क्या है, एक-से-कई (संभावित) के लिए रिश्ते को देखना है ! यह वही है जो ऑब्जर्वर पैटर्न को पूरा करने के लिए डिज़ाइन किया गया था।

जबकि अधिकांश सेटअपों में एक समय में संबंधित होने के लिए केवल एक दृश्य होता है, ऐसा कुछ भी नहीं है जो MVC आर्किटेक्चरल पैटर्न को एक बार में कई बार अपडेट करने से रोकता है! पारंपरिक CRUD वेब अनुप्रयोगों के साथ काम करना लोगों को एक-से-एक तरीके से सोचना पड़ता है , लेकिन यह सबसे छोटा उदाहरण है कि ऑब्जर्वर पैटर्न कैसे काम कर सकता है ( एक-से-कई अन्य होने के नाते )।

इस प्रकार, यदि आपके पास एक Modelऔर एक से अधिक है Views, तो सभी कार्यान्वयन कोड को अपडेट करने का संभावित सिरदर्दViews' क्योंकि आपने Model'sएपीआई / विधियों में कुछ बदल दिया है अब तीव्र हो जाता है

के उदाहरणों को नहींViews , डेटा पास करें Models

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.