2013-03-01 76 views
1

我有一些數據,有時候這些數據是空白的。我寧願使用一種幫助器方法,而不是在視圖上製作一堆瘋狂的邏輯,如果它存在,它將呈現數據,並呈現一些HTML,當字符串爲空/空時,它只表示「N/A」。MVC Razor:助手方法在空時渲染備用內容

理想語法:@Helpers.RenderThisOrThat(Model.CustomerPhone)

如果Model.CustomerPhone(字符串)是空的,它將使而不是此替代HTML:<span class='muted'>N/A</span>

下面是我們到目前爲止有:

@helper RenderThisOrThat(string stringToRender, string methodToGetAlternateText = null) 
{ 
    @RenderThisOrThat(MvcHtmlString.Create(stringToRender), methodToGetAlternateText) 
} 

@helper RenderThisOrThat(MvcHtmlString stringToRender, string methodToGetAlternateText = null) 
{ 
    if (string.IsNullOrWhiteSpace(stringToRender.ToHtmlString())) 
    { 
     if (!string.IsNullOrWhiteSpace(methodToGetAlternateText)) { 
      @methodToGetAlternateText 
     } 

     <span class='muted'>N/A</span> 
    } 

    @stringToRender 
} 

該作品沒關係,直到我們想將除字符串之外的其他東西傳遞給任一參數。例如,當我們有一個電子郵件地址時,我們希望它是該電子郵件的鏈接,而不僅僅是電子郵件的字符串。

@Helpers.RenderThisOrThat(@<a href="mailto:@Html.DisplayFor(m => m.CustomerEmail)">@Html.DisplayFor(m => m.CustomerEmail)</a>)

它給我們的錯誤:「無法轉換lambda表達式到類型‘串’,因爲它不是一個委託類型」

我們是在爲如何使這項工作的損失..這裏有什麼幫助嗎?

+0

你能寫這樣的代碼嗎?除了你的幫助方法,我不認爲剃刀可以解釋這個 – 2013-03-01 15:07:17

+0

你是否引用'System.Linq;'? – Kami 2013-03-01 15:08:42

+0

@Kami什麼是LINQ的? – 2013-03-01 15:09:25

回答

2

你正在尋找一個幫手,將採取字符串和:

  1. 如果字符串不爲空,呈現該字符串。
  2. 如果字符串不爲空,則渲染給定的模板。
  3. 如果字符串爲空,則呈現「N/A」html。
  4. 如果字符串爲空,則渲染給定的模板。

將剃刀塊作爲參數傳遞給函數時,剃鬚刀將該塊封裝爲Func。更改幫助函數中的參數以獲取該類型的委託,並且不要忘記調用這些委託(我選擇傳遞null)。

這些助手應該處理這些情況。

@helper RenderThisOrThat(string stringToRender, Func<object, IHtmlString> leftTemplate = null, Func<object, IHtmlString> rightTemplate = null) 
{ 
    var shouldRenderLeft = !string.IsNullOrWhiteSpace(stringToRender); 
    leftTemplate = leftTemplate ?? (o => MvcHtmlString.Create(stringToRender)); 
    @RenderThisOrThat(shouldRenderLeft, leftTemplate, rightTemplate) 
} 

@helper RenderThisOrThat(bool shouldRenderLeft, Func<object, IHtmlString> leftTemplate, Func<object, IHtmlString> rightTemplate = null) 
{ 
    var shouldRenderRight = !shouldRenderLeft; 
    if (shouldRenderRight) 
    { 
     if (rightTemplate != null) 
     { 
      @rightTemplate(null) 
     } 
     else 
     { 
      <span class='muted'>N/A</span> 
     } 
    } 
    else 
    { 
     @leftTemplate(null) 
    } 
} 

實例

1. @Helpers.RenderThisOrThat(Model.StringWithBob) 
2. @Helpers.RenderThisOrThat(Model.StringWithNull) 
3. @Helpers.RenderThisOrThat(Model.StringWithBob, @<span>I'm @Model.StringWithBob</span>) 
4. @Helpers.RenderThisOrThat(Model.StringWithNull, @<span>I'm @Model.StringWithBob</span>) 
5. @Helpers.RenderThisOrThat(Model.StringWithBob, @<span>I'm @Model.StringWithBob</span>, @<span>What about Bob?</span>) 
6. @Helpers.RenderThisOrThat(Model.StringWithNull, @<span>I'm @Model.StringWithBob</span>, @<span>What about Bob?</span>) 

將輸出:

  1. Bob
  2. <span class='muted'>N/A</span>
  3. <span>I'm Bob</span>
  4. <span class='muted'>N/A</span>
  5. <span>I'm Bob</span>
  6. <span>What about Bob?</span>
+1

這太棒了!另外,既然你是我的同事,我所要做的就是接受這個答案,然後'hg pull'! – 2013-03-01 21:05:04

2

這是一個非常複雜的解決方案,以一個簡單的問題。您不需要創建複雜的視圖,事實上,您應該使用Editor/DisplayTemplate,然後將您的邏輯放在模板中,並且只執行一次,而不需要額外包含輔助函數或其他任何東西。

你也可以在這裏更進一步,因爲在這種情況下,你正在渲染一個電子郵件地址。您將DataType屬性應用於模型,然後指定電話號碼呈現類型。

public class MyModel { 
    [DataType(DataType.PhoneNumber)] 
    public string PhoneNumber {get;set;} 
} 

然後你在〜/查看/共享稱爲DisplayTemplates創建一個文件夾,該文件夾中創建一個名爲PhoneNumber.cshtml文件,在裏面你這樣做:

@model string 

@if (string.IsEmptyOrWhiteSpace(Model)) { 
    @:<span class='muted'>N/A</span> 
} else { 
    @: <span>@Model</span> 
} 

然後,在你的看法:

@Html.DisplayFor(x => x.PhoneNumber) 

就是這樣,在您的視圖中沒有複雜的邏輯,沒有任何地方的幫手功能受到污染。這很簡單,容易和可維護。您也可以爲Email地址執行相同的操作,因爲也有EmailAddress數據類型。

MVC有很多非常好的功能內置,大多數人根本沒有使用,因爲他們沒有花任何實時學習它。

+0

Upvoted。有任何網頁/教程的網址,涵蓋大多數人錯過的MVC設施(如DataType屬性)? – 2013-05-16 10:55:59

+1

@RobertOschler - http://channel9.msdn.com/Events/aspConf/aspConf/ASP-NET-MVC-Tips-Tricks-and-Hidden-Gems – 2013-05-16 13:55:39

+0

感謝您的視頻鏈接。 – 2013-05-16 14:15:01