रेजर नेस्टेड लेआउट कैस्केडिंग सेक्शन के साथ


80

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

इसलिए, मैं इस डिजाइन पर विचार कर रहा हूं:

नियोजित दृश्य आरेख

हालांकि, मैं फोन करने के लिए सक्षम होने के लिए चाहते हैं RenderSection, नीचे की परत में _Common.cshtml,, और यह एक अनुभाग है कि शीर्ष स्तर में परिभाषित किया गया है प्रस्तुत करना है Detail.cshtml। यह काम नहीं करता है: RenderSectionजाहिरा तौर पर केवल उन वर्गों को प्रस्तुत करता है जो अगली परत को परिभाषित करते हैं।

बेशक, मैं प्रत्येक त्वचा में प्रत्येक अनुभाग को परिभाषित कर सकता हूं। उदाहरण के लिए, यदि किसी खंड को परिभाषित _Commonकरने की आवश्यकता है , तो मैं इसे प्रत्येक में रखता हूं और यह काम करता है:RenderSection("hd")Detail_Skin

@section hd {
    @RenderSection("hd")
}

इसका परिणाम कोड के कुछ दोहराव में होता है (क्योंकि प्रत्येक त्वचा में अब यही खंड होना चाहिए) और आम तौर पर गड़बड़ महसूस होता है। मैं रेजर के लिए अभी भी नया हूं, और ऐसा लगता है कि मुझे कुछ स्पष्ट याद आ रहा है।

डिबगिंग करते समय, मैं WebViewPage.SectionWritersStack में परिभाषित वर्गों की पूरी सूची देख सकता हूं। अगर मैं सिर्फ देने से पहले पूरी सूची के माध्यम से देखने के लिए रेंडरसेन को बता सकता हूं, तो मुझे वह अनुभाग मिलेगा जिसकी मुझे आवश्यकता है। काश, SectionWritersStack गैर-सार्वजनिक है।

वैकल्पिक रूप से, यदि मैं लेआउट पृष्ठों के पदानुक्रम तक पहुँच सकता हूं और प्रत्येक अलग संदर्भ में रेंडरसेन के निष्पादन का प्रयास कर सकता हूं, तो मुझे उस अनुभाग का पता लग सकता है जिसकी मुझे आवश्यकता है। मुझे शायद कुछ याद आ रहा है, लेकिन मुझे ऐसा करने का कोई रास्ता नहीं दिख रहा है।

क्या इस लक्ष्य को पूरा करने का कोई तरीका है, उस पद्धति के अलावा जो मैंने पहले ही बताई है?

जवाबों:


35

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

इस बीच, मैंने इस विषय पर कुछ दो ब्लॉग पोस्ट लिखे हैं:


3
प्रतिक्रिया के लिए धन्यवाद, मैं इस सिंटैक्स (ऊपर के रूप में) का उपयोग करके नेस्टेड वर्गों के साथ खेल रहा हूं: @ एसेंशन एचडी {@ रेंडरस्फेक्शन ("एचडी")} ... जो वास्तव में मेरे लिए काम करता है और ऐसा लगता है कि मैं मौजूदा एनएपी मास्टरपीस को दोहरा सकता हूं। । मुझे लगता है कि मैंने सवाल को थोड़ा गलत समझा और सोचा कि यह काम नहीं करेगा।
मार्क रेडमैन

2
सवाल और जवाब दोनों ने बहुत मदद की और मैं भी मानता हूं कि रेजर के अगले संस्करण में इसे आसान बनाया जाना चाहिए। और आपको आंशिक विचारों को भी वर्गों को लागू करने में सक्षम होने की संभावना को सक्षम करना चाहिए, जो इस समय समर्थित नहीं है।
घोड़ी

1
@ श्रेक मुझे नहीं लगता कि इस क्षेत्र में कुछ भी बदला है। आप पर सुविधा अनुरोधों दर्ज कर सकते हैं UserVoice साइट या पर कीड़े codeplex
marcind

1
@marcind मेरे जवाब पर एक नज़र डालें। मुझे लगता है कि यह वही है जो ओपी ने पूछा है। सही?
एलिरेज़ा नूरी

1
MVC 5 बाहर है। किसी भी अद्यतन? Alirzea ने कहा कि वह एक समाधान मिला, लेकिन यह OPs समस्या से मेल नहीं खाता क्योंकि यह खंडों को बिल्कुल भी संदर्भित नहीं करता था।
स्नेक

17
@helper ForwardSection( string section )
{
   if (IsSectionDefined(section))
   {
       DefineSection(section, () => Write(RenderSection(section)));
   }
}

क्या यह काम करेगा?


क्या आप मध्यवर्ती परत में इसका उपयोग कर रहे हैं? बहुत ज्यादा इस विस्तार वर्ग के रूप में ही है ? यदि हां, तो समस्या को हल करने के बजाय, अनुभाग को पुन: घोषित करते समय यह अधिक सुविधा है? बस मुझे समझ में आ रहा है, क्योंकि मुझे इस चर्चा में देर हो गई है।
drzaus

मेरे लिए, यह एकमात्र समाधान था जिसने काम किया। यदि आधार लेआउट में एक खंड सशर्त रूप से प्रस्तुत किया गया है, तो MVC एक रनटाइम त्रुटि को फेंक देगा जब तक कि उस खंड को मध्यवर्ती परत में सशर्त रूप से परिभाषित नहीं किया जाता (जैसे यह)। धन्यवाद @ कैंडी!
माइकल

क्या उन सभी वर्गों को अग्रेषित करना संभव है जो वर्तमान में परिभाषित हैं?
नवर्थ

4

मुझे यकीन नहीं है कि यह MVC 3 में संभव है, लेकिन MVC 5 में मैं निम्नलिखित चाल का उपयोग करके सफलतापूर्वक ऐसा करने में सक्षम हूं:

में ~/Views/Shared/_Common.cshtmlलिखने की तरह अपने सामान्य एचटीएमएल कोड:

<!DOCTYPE html>
<html lang="fa">
<head>
    <title>Skinnable - @ViewBag.Title</title>
</head>
<body>
@RenderBody()
</body>
</html>

इन ~/Views/_ViewStart.cshtml:

@{
    Layout = "~/Views/Shared/_Common.cshtml";
}

अब आपको बस इतना करना है _Common.cshtmlकि Layoutसभी खालों का उपयोग करें । उदाहरण के लिए, इसमें ~/Views/Shared/Skin1.cshtml:

@{
    Layout = "~/Views/Shared/_Common.cshtml";
}

<p>Something specific to Skin1</p>

@RenderBody()

अब आप अपने मानदंडों के आधार पर नियंत्रक या दृश्य में अपने लेआउट के रूप में त्वचा को निर्धारित कर सकते हैं। उदाहरण के लिए:

    public ActionResult Index()
    {
        //....
        if (user.SelectedSkin == Skins.Skin1)
            return View("ViewName", "Skin1", model);
    }

यदि आप ऊपर दिए गए कोड को चलाते हैं, तो आपको Skin1.cshtmlऔर सामग्री दोनों के साथ एक HTML पेज मिलना चाहिए_Common.cshtml

संक्षेप में, आप (त्वचा) लेआउट पृष्ठ के लिए लेआउट सेट करेंगे।


मुझे इस दृष्टिकोण के साथ समस्या थी क्योंकि अनुभाग दिखाई नहीं देंगे। मैंने blogs.msdn.microsoft.com/marcinon/2010/12/15/…
Spikolynn

1

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

रेजर व्यू इंजन के साथ एक आंशिक दृश्य ASP.NET MVC 3 से विशिष्ट खंडों में सामग्री को इंजेक्ट करना

बाल लेआउट / दृश्य / आंशिक में घोषणा

@using (Html.Delayed()) {
    <b>show me multiple times, @Model.Whatever</b>
}

किसी भी अभिभावक में प्रस्तुत करना

@Html.RenderDelayed();

अधिक उपयोग-मामलों के लिए उत्तर लिंक देखें, जैसे केवल एक विलंबित ब्लॉक का प्रतिपादन करना, भले ही दोहराए गए दृश्य में घोषित किया गया हो, विशिष्ट विलंब ब्लॉक प्रदान करना आदि।

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