2012-08-30 177 views
12

通常我通過@ Html.RenderModel呈現我的表單,但是這次我有一個複雜的呈現邏輯,我手動呈現它。我決定爲一個屬性創建一個編輯器模板。下面是代碼(複製從默認的對象編輯器模板實現粘貼):屬性的ASP.NET MVC編輯器模板

<%@ 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 

但它沒有工作:不管標籤渲染顯示名稱的和編輯器根本沒有呈現(在手錶Html.Editor(modelMetadata.PropertyName顯示空字符串)。我做錯了什麼?

回答

0

什麼類型是「x.SomeProperty」?我現在會假設它是類型稱爲Property。

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) 

如果您沒有爲EditorFormer幫助程序提供templatename,它會找到名稱匹配的編輯模板 SomeProperty的類型

更新:

爲了使字符串的自定義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

SomeProperty的類型是字符串,所以我期望文本框被呈現 – SiberianGuy

+0

查看更新的答案 –

+0

我不需要模板字符串,我需要一個通用模板的任何屬性 – SiberianGuy

12

要調用的編輯器編輯器。作爲@ RPM1984在@this中改寫@ darin-dmitrov回答:在給定視圖特定上下文中,您只能在運行時使用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")

而且,關於標籤,無論是渲染顯示名稱,防止標籤的渲染是否有不顯示名稱,改變你如果條件!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,但創建的複雜模型的屬性編輯器列表中的循環中。這些調用中的每一個都會調用相應的編輯器(即,對於字符串,它將顯示string.ascx等),並且僅當您有一些不是字符串的「未知」屬性並且沒有特定的編輯器時(即byte [])它會調用object.ascx它,但這是不呼籲爲當前屬性編輯器(你正在嘗試做的):

的對象模板的主要職責是顯示一個複雜對象的所有屬性,以及每個屬性的標籤。但是,它也負責顯示模型NullDisplayText的值(如果它爲null),並且還負責確保您只顯示一個屬性級別(也稱爲對象的「淺潛點」)。在接下來的博客文章中,我們將討論如何自定義此模板,包括執行「深度潛水」操作。


摘要

短版:

更多的編輯器相同的屬性基本上是功能上的差異的解決方案(「爲是/否我想在這裏無線電集團有下拉) 「,對於視覺差異,應該使用部分視圖,因爲您可以儘可能多地嵌套它們,因爲您明確地按名稱調用它們,因此沒有限制,您有責任防止任何潛在的遞歸。

龍版本:

我一直在研究這個,因爲我有同樣的問題,我使用的編輯器模板來呈現<li><td>元素(取決於配置/主題),並從裏面調用另一個編輯器其中包含標籤和輸入(對於兩種情況都是相同的,但是如果屬性是bool,則輸入在標籤之前),在那裏我再次調用第三個模板進行輸入(以防止爲標籤/輸入和輸入/標籤場景複製代碼),但這不起作用。雖然我沒有找到有關msdn或其他相關資源的解釋,但我發現編輯器沒有提供的唯一場景是,當您想爲當前編輯器的上下文屬性渲染編輯器(所以它實際上正是我已經引用:「在一個給定的視圖特定的上下文中,你只能在運行時使用1個給定類型的模板。」)。在想了解更多這方面的信息之後,現在我相信他們是正確的,只能用一個編輯器渲染屬性x。您可以根據需要爲屬性x編輯儘可能多的編輯器,但只有使用多個模板才能渲染一個屬性。任何用於呈現屬性x的模板都可以使用其他模板呈現屬性x的PARTS,但不能多次使用(相同或不同)x的編輯器(相同的邏輯適用於具有兩個或更多屬性x(相同類型和名稱)在同一模型)。

此外,如果你可以插入當前財產另一模板到當前模板,使鏈接任意數量的用於當前屬性模板,並可以很容易地引起遞歸,所以這種或那種方式會導致你計算器: )

+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

你說得對,問題是我在這裏有種遞歸。但我其實並沒有看到ASP.NET MVC無法解決它的任何原因。 – SiberianGuy

相關問題