2010-11-12 21 views
7

मैं एक MVC आवेदन जो वर्तमान में विचारों का एक बहुत gennerate को EditorFor का उपयोग करता बना रहा हूं में डिफ़ॉल्ट EditorFor टेम्पलेट: चुन कर ओवरराइड करना। पूरा दृश्य मूल रूप से केवल एक संपादकफॉर्म मॉडल है, और यह बहुत अच्छा काम करता है। हालांकि, मैं एक छोटी सी समस्या है, जो मैं के लिए एक समाधान खोजने के लिए नहीं कर पा रहे पहुँच गए हैं, और यह महत्वपूर्ण है कि जिस तरह से मैं करने के लिए इसकी आवश्यकता है काम करता है, और कहा कि जब EditorFor एक अंतरफलक रेंडर करने के लिए कोशिश कर रहा है। बाइंडिंग और इस तरह की हर चीज का ख्याल रखा गया है, लेकिन समस्या यह है कि संपादक के लिए यह देखता है कि यह एक इंटरफ़ेस है, और "ऑब्जेक्ट" टेम्पलेट में डिफ़ॉल्ट है। मुझे लगता है मैं इसकी आवश्यकता सभी इंटरफ़ेस अगर यह उनमें से किसी से मेल खाता देखने के लिए वर्तमान गर्त देखने के लिए यह इंटरफ़ेस को देखो और उस नाम का कोई टेम्पलेट पाते हैं या नहीं, और अगर यह नहीं कर सकते हैं की जरूरत है,।ASP.NET MVC 3 आर सी

इंटरफेस: इसे और अधिक बस इस उदाहरण पर नजर व्याख्या करने के लिए

public interface IAppProvider 
{ 
    string Name { get; set; } 
} 

public interface IAppMusicProvider : IAppProvider 
{ 
    int GetPlaylistCount(); 
} // Yeah, I know, this interface is not smart, but it's only for show. 

मैं अब मॉडल = "IAppMusicProvider" के साथ एक दृश्य बनाते हैं, और Html.EditorForModel() चलाते हैं, मैं इसे खोजने के लिए "~ दृश्य की जरूरत है \ साझा \ EditorTemplates \ IAppProvider.cshtml "-template। क्या यह कोई आसान तरीका है जिसे मैं प्राप्त कर सकता हूं?

उत्तर

1

आप [TemplateHint] विशेषता का उपयोग कर की कोशिश की?

+0

हाँ, यह काम करता है, लेकिन यह समस्या को हल एक तरीका नहीं है (या बल्कि मैं इस्तेमाल किया '[डेटा टाइप] वास्तव में विशेषता)। आवेदन मैं बना रहा हूं प्लग इन चलाने जा रहा है, और मैं इसे केवल इंटरफ़ेस की स्थापना, और उपयोगकर्ता '[डेटा प्रकार (" IAppProvider ")]' करने के लिए सभी प्लगइन-डेवलपर्स के लिए मजबूर करने नहीं होने से काम करने के लिए की जरूरत है। – Alxandr

+0

टेम्पलेट को इंटरफ़ेस के समान नाम देने का प्रयास करें? अगर मुझे याद है कि वे केवल दो विकल्प हैं। – jfar

+0

यह या तो काम नहीं करेगा, क्योंकि टेम्पलेट को सभी 'IAppProvider' के लिए काम करने की आवश्यकता है। मैं इस डिफ़ॉल्ट व्यवहार को ओवरराइड करने के लिए कुछ रास्ता ढूंढ रहा हूं, ताकि यदि मैं एक IAppProvider- कार्यान्वयन इंटरफ़ेस की आपूर्ति करता हूं, तो यह IAppProvider-template का उपयोग करेगा। इसे शायद एमवीसी में कहीं भी कोड किया जाना चाहिए (कुछ घटक जिन्हें बदलने की जरूरत है, जैसे आप कंट्रोलर फैक्ट्री आदि के साथ कर सकते हैं), लेकिन मुझे यह भी नहीं पता कि कहां से शुरू करना है। – Alxandr

1

आप ModelMetadataProvider में ModelMetadata.TemplateHint बदलने का प्रयास कर सकता है।

public class AbstractTypeTemplateSupportingModelMetadataProvider : ModelMetadataProvider 
{ 
    private readonly ModelMetadataProvider wrapped; 

    public AbstractTypeTemplateSupportingModelMetadataProvider(ModelMetadataProvider wrapped) 
    { 
     this.wrapped = wrapped; 
    } 

    public override IEnumerable<ModelMetadata> GetMetadataForProperties(object container, Type containerType) 
    { 
     var result = this.wrapped.GetMetadataForProperties(container, containerType).ToList(); 
     result.ForEach(ChangeTemplateHint); 

     return result; 
    } 

    public override ModelMetadata GetMetadataForProperty(Func<object> modelAccessor, Type containerType, string propertyName) 
    { 
     var result = this.wrapped.GetMetadataForProperty(modelAccessor, containerType, propertyName); 
     ChangeTemplateHint(result); 

     return result; 
    } 

    public override ModelMetadata GetMetadataForType(Func<object> modelAccessor, Type modelType) 
    { 
     var result = this.wrapped.GetMetadataForType(modelAccessor, modelType); 
     ChangeTemplateHint(result); 

     return result; 
    } 

    private void ChangeTemplateHint(ModelMetadata source) 
    { 
     if (source.Model is IAppProvider) //Or use source.ModelType if you want to support the model being null. 
      source.TemplateHint = typeof(IAppProvider).Name; 
    } 
} 

और अपने स्टार्ट-अप तर्क में: एक तरह से यह करने के लिए डेकोरेटर पैटर्न के साथ है

ModelMetadataProviders.Current = new AbstractTypeTemplateSupportingModelMetadataProvider(ModelMetadataProviders.Current); 
संबंधित मुद्दे