2012-08-30 13 views
12

आमतौर पर मैं अपने फॉर्म @ एचटीएमएल.रेंडरमोडेल द्वारा प्रस्तुत करता हूं, लेकिन इस बार मेरे पास एक जटिल प्रतिपादन तर्क है और मैं इसे मैन्युअल रूप से प्रस्तुत करता हूं। मैंने एक संपत्ति के लिए एक संपादक टेम्पलेट बनाने का फैसला किया।संपत्ति के लिए एएसपी.नेट एमवीसी संपादक टेम्पलेट

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> 
<% var modelMetadata = ViewData.ModelMetadata; %> 
<% if (modelMetadata.HideSurroundingHtml) { %> 
    <%= Html.Editor(modelMetadata.PropertyName) %> 
<% } else { %> 
    <% if (!String.IsNullOrEmpty(Html.Label(modelMetadata.PropertyName).ToHtmlString())) { %> 
     <div class="editor-label"><%= Html.Label(modelMetadata.PropertyName) %></div> 
    <% } %> 
    <div class="editor-field"> 
     <%= Html.Editor(modelMetadata.PropertyName) %> 
     <%= Html.ValidationMessage(modelMetadata.PropertyName) %> 
    </div> 
<% } %> 

यहाँ है तो मैं इसका उपयोग और:: यहाँ कोड (कॉपी डिफ़ॉल्ट वस्तु संपादक टेम्पलेट कार्यान्वयन से चिपकाया) है

@Html.EditorFor(x => x.SomeProperty, "Property") //"Property" is template above 

लेकिन यह काम नहीं किया: लेबल DisplayName की परवाह किए बिना गाया जाता है और संपादकों को बिल्कुल नहीं दिया जाता है (घड़ियाँ Html.Editor में (modelMetadata.PropertyName खाली स्ट्रिंग दिखाता है)। मैं क्या गलत कर रहा हूं?

उत्तर

0

"x.SomeProperty" किस प्रकार का है? मैं अब के लिए मान ले रहा हूँ प्रकार को संपत्ति कहा जाता है।

MyModel.cs

public class MyModel 
{ 
    public Property SomeProperty { get; set; } 
} 

Property.cs

public class Property 
{ 
    [Display(Name="Foo")] 
    public int Value { get; set; } 
} 

दृश्य/साझा/EditorTemplates/Property.cshtml

@model MvcApplication1.Models.Property 

@Html.LabelFor(model => model.Value) 
@Html.EditorFor(model => model.Value) 
@Html.ValidationMessageFor(model => model.Value) 

MyView.cshtml

@Html.EditorFor(model=>model.SomeProperty) 

यदि आप संपादक के लिए templatename प्रदान नहीं करते हैं तो सहायक में यह editortemplate पाता है जो नाम से मेल खाता है कुछ प्रॉपर्टी का टाइप

अद्यतन:

स्ट्रिंग के लिए एक कस्टम editortemplate कमाने के लिए आप कार्य करें:

मॉडल

public class MyModel 
{ 
    public string SomeProperty { get; set; } 
} 

दृश्य:

@Html.EditorFor(model => model.SomeProperty,"Property") 

या वैकल्पिक रूप से:

मॉडल:

public class MyModel 
{ 
    [DataType("Property")] 
    public string SomeProperty { get; set; } 
} 

दृश्य:

@Html.EditorFor(model => model.SomeProperty) 

दृश्य/साझा/EditorTemplates/Property.cshtml:

@model string 

@Html.Raw("I'm using property editortemplate:") 
@Html.Label(ViewData.ModelMetadata.PropertyName) 
@Html.Editor(ViewData.ModelMetadata.PropertyName) 
@Html.ValidationMessage(ViewData.ModelMetadata.PropertyName) 
+0

कुछ प्रॉपर्टी का प्रकार स्ट्रिंग है, इसलिए मुझे उम्मीद है कि टेक्स्टबॉक्स – SiberianGuy

+0

अपडेट किया गया जवाब देखें –

+0

मुझे स्ट्रिंग के लिए टेम्पलेट की आवश्यकता नहीं है, मुझे किसी भी संपत्ति के लिए एक सामान्य टेम्पलेट चाहिए – SiberianGuy

12

आप अपने संपादक से संपादक बुला रहे हैं। जैसा कि @ RPM1984 this में टिप्पणी में @ डारिन-डिमिटोव को दोहराता है उत्तर: आपके पास किसी दिए गए दृश्य के लिए रनटाइम पर केवल 1 टेम्पलेट का उपयोग किया जा सकता है, किसी विशेष दृश्य में।

आप संपादक के बजाय पाठ बॉक्स रेंडर करने के लिए आपके विचार बदलते हैं, तो यह काम करता है, मैं बस की कोशिश की:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> 
<% var modelMetadata = ViewData.ModelMetadata; %> 
<% if (modelMetadata.HideSurroundingHtml) 
    { %> 
    <%= Html.Editor(modelMetadata.PropertyName) %> 
<% } 
    else 
    { %> 
    <% if (!String.IsNullOrEmpty(modelMetadata.DisplayName)) 
     { %> 
     <div class="editor-label"><%= Html.Label(modelMetadata.PropertyName) %></div> 
    <% } %> 
    <div class="editor-field"><%= Html.TextBox(modelMetadata.PropertyName) %> <%= Html.ValidationMessage(modelMetadata.PropertyName) %></div> 
<% } %> 

आप कुछ और के बजाय पाठ बॉक्स (यानी ड्रॉपडाउन सूची) प्रस्तुत करना चाहते हैं, आप तय करने की जरूरत है कि उस संपत्ति के लिए अपने टेम्पलेट के अंदर और इसे प्रस्तुत करें। या, यदि आप अधिक संपादकों के लिए कुछ सामान्य है, मैं आमतौर पर निकालने कि साझा फ़ोल्डर में आंशिक दृश्य में, और सिर्फ Html.Partial("ViewName")

का उपयोग और, लेबल के बारे में DisplayName की परवाह किए बिना गाया जाता है, अगर वहाँ प्रतिपादन से लेबल को रोकने के लिए !String.IsNullOrEmpty(modelMetadata.DisplayName) (मैं पहले से ही इसे उस तरह से मुख्य कोड ब्लॉक में डाल) करने के लिए कोई प्रदर्शन नाम, अपने अगर हालत बदल

संपादित यह संपादन डिफ़ॉल्ट संपादक टेम्पलेट object.ascx से संबंधित सवाल को दर्शाता है। यह object.ascx का कोड, Brad Wilson's blog से लिया है:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %> 
<% if (ViewData.TemplateInfo.TemplateDepth > 1) { %> 
    <%= ViewData.ModelMetadata.SimpleDisplayText%> 
<% } 
    else { %>  
    <% foreach (var prop in ViewData.ModelMetadata.Properties.Where(pm => pm.ShowForEdit 
         && !ViewData.TemplateInfo.Visited(pm))) { %> 
     <% if (prop.HideSurroundingHtml) { %> 
      <%= Html.Editor(prop.PropertyName) %> 
     <% } 
      else { %> 
      <% if (!String.IsNullOrEmpty(Html.Label(prop.PropertyName).ToHtmlString())) { %> 
       <div class="editor-label"><%= Html.Label(prop.PropertyName) %></div> 
      <% } %> 
      <div class="editor-field"> 
       <%= Html.Editor(prop.PropertyName) %> 
       <%= Html.ValidationMessage(prop.PropertyName, "*") %> 
      </div> 
     <% } %> 
    <% } %> 
<% } %> 

इस कोड को वास्तव में संपादक के अंदर से Html.Editor कहता है, लेकिन एक पाश जो जटिल मॉडल के गुणों के लिए संपादकों की सूची बनाता है अंदर। इनमें से प्रत्येक कॉल संबंधित संपादक का आह्वान करेगी (यानी स्ट्रिंग के लिए यह स्ट्रिंग.एक्सएक्स इत्यादि दिखाएगी), और केवल तभी यदि आपके पास कुछ "अज्ञात" संपत्ति है जो स्ट्रिंग नहीं है और इसके लिए कोई विशिष्ट संपादक नहीं है (यानी बाइट []) यह इसके लिए object.ascx लागू करेगा, लेकिन इस नहीं वर्तमान संपत्ति के लिए संपादक (तुम क्या करने कोशिश कर रहे हैं) बुला है:

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


सारांश

लघु संस्करण: एक ही संपत्ति के लिए

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

लांग संस्करण:

मैं इस की जांच की है, के रूप में मैं एक ही समस्या है, मैं <li> या <td> तत्व प्रस्तुत करना संपादक टेम्पलेट का उपयोग कर रहा (पर config/विषय निर्भर करता है) और से यह एक और संपादक फोन के अंदर जिसमें लेबल और इनपुट शामिल है (दोनों मामलों के लिए समान है, लेकिन यदि संपत्ति बूल है तो इनपुट लेबल से पहले है), जहां मैं इनपुट के लिए तीसरा टेम्पलेट कॉल कर रहा हूं (लेबल/इनपुट और इनपुट/लेबल परिदृश्यों के लिए डुप्लिकेटिंग कोड को रोकने के लिए), लेकिन यह काम नहीं करता। हालांकि मुझे एमएसडीएन या अन्य प्रासंगिक स्रोत पर स्पष्टीकरण नहीं मिला, मुझे पता चला कि एकमात्र परिदृश्य जब संपादक कुछ भी नहीं देता है तब आप उस संपत्ति के लिए संपादक प्रस्तुत करना चाहते हैं जो वर्तमान संपादक का संदर्भ है (इसलिए यह वास्तव में वास्तव में है जो मैं पहले से ही उद्धृत: "किसी दिए गए दृश्य विशेष संदर्भ में, आपके पास किसी दिए गए प्रकार के लिए रनटाइम पर केवल 1 टेम्पलेट का उपयोग किया जा सकता है।")।इसके बारे में कुछ और सोचने के बाद, मुझे विश्वास है कि वे इस सीमा को लागू करने में सही हैं, क्योंकि संपत्ति एक्स को केवल एक संपादक का उपयोग करके प्रस्तुत किया जा सकता है। जैसा कि आप चाहते हैं संपत्ति प्रॉपर्टी एक्स के लिए आपके पास कई संपादक हो सकते हैं, लेकिन आप एक से अधिक टेम्पलेट का उपयोग कर एक बार एक प्रॉपर्टी प्रस्तुत नहीं कर सकते हैं। प्रॉपर्टी एक्स को रेंडर करने के लिए आपके टेम्पलेट्स में से कोई भी प्रॉपर्टी एक्स के पार्ट्स को प्रस्तुत करने के लिए अन्य टेम्पलेट्स का उपयोग कर सकता है, लेकिन आप एक से अधिक बार एक्स के लिए (समान या अलग) संपादक का उपयोग नहीं कर सकते (उसी तर्क को दो या दो से अधिक गुण x (समान प्रकार के रूप में लागू होता है) और नाम) एक ही मॉडल पर)।

इसके अलावा, अगर आप वर्तमान टेम्पलेट में वर्तमान संपत्ति के लिए एक और टेम्पलेट डाल सकता है, मौजूदा प्रॉपर्टी के लिए टेम्पलेट्स के किसी भी संख्या चेनिंग सक्षम बनाता है, और आसानी से प्रत्यावर्तन, तो एक तरह से पैदा कर सकता है या किसी अन्य के यह stackoverflow पर ले जाएगा:)

+0

हां, मैं एक संपादक से संपादक को बुला रहा हूं लेकिन यह वही होता है जब आप डिफ़ॉल्ट ऑब्जेक्ट संपादक टेम्पलेट के साथ RenderModel का उपयोग करते हैं। और यह ऑब्जेक्ट संपादक टेम्पलेट के लिए काम करता है। तो मेरा कोड इससे अलग कैसे है? – SiberianGuy

+1

क्या आप http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-3-default-templates.html से डिफ़ॉल्ट टेम्पलेट का जिक्र कर रहे हैं? एक अंतर है, prop.PropertyName का उपयोग जटिल मॉडल के गुणों के लिए संपादक को कॉल करने के लिए किया जाता है, मॉडल के लिए <% = ViewData.ModelMetadata.SimpleDisplayText%> का उपयोग किया जाता है। याद रखें कि सभी गुणों के लिए उनके डिफ़ॉल्ट संपादक को कॉल किया जाएगा, इसलिए स्ट्रिंग प्रॉपर्टी इत्यादि के लिए स्ट्रिंग, इसलिए यदि कोई "विशिष्ट" संपादक नहीं है, तो यह ऑब्जेक्ट को टेक्स्ट टेक्स्ट के साथ बुलाएगा, क्योंकि "अज्ञात" ऑब्जेक्ट संपादित नहीं किया जा सकता है। –

+0

आप सही हैं, समस्या यह है कि मेरे यहां एक तरह का रिकर्सन है। लेकिन मुझे वास्तव में कोई कारण नहीं दिख रहा है कि क्यों एएसपी.नेट एमवीसी इसे हल नहीं कर सकता है। – SiberianGuy

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