2013-03-01 5 views
1

У меня есть некоторые данные, и иногда эти данные пустые. Вместо того, чтобы сделать кучу сумасшедшей логики в моем представлении, я предпочел бы использовать вспомогательный метод, который будет отображать данные, если он существует, и отобразить некоторый HTML, который просто говорит «N/A», когда строка пуста/null.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>)

Это дает нам сообщение об ошибке: «Не удается преобразовать лямбда-выражения к типу„строка“, потому что это не тип делегата»

Мы в недоумении, как сделать эту работу .. любая помощь здесь?

+0

Можете ли вы написать такой код? Помимо вашего вспомогательного метода, я не думаю, что Razor может интерпретировать это. –

+0

Вы ссылаетесь на 'System.Linq;'? – Kami

+0

@ Ками, для чего LINQ? –

ответ

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»! –

2

Это очень сложное решение простой проблемы. Вам не нужно создавать сложные представления, на самом деле вы должны использовать редактор/DisplayTemplate, тогда вы помещаете свою логику в шаблон, и это делается один раз, без необходимости дополнительного включения вспомогательных функций или чего-то еще.

Вы также можете сделать еще один шаг здесь, потому что в этом случае вы отправляете адрес электронной почты. Вы применяете атрибут DataType к своей модели, а затем указываете тип отображения номера телефона.

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

Затем вы создаете папку в ~/Views/Shared называемых DisplayTemplates и в этой папке создать файл с именем PhoneNumber.cshtml, в нем вы делаете это:

@model string 

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

Затем, по вашему мнению, :

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

Это не сложная логика, на ваш взгляд, нет встроенных вспомогательных функций. Это просто, легко и удобно. Вы можете сделать то же самое для адреса электронной почты, так как есть тип данных EmailAddress.

MVC обладает множеством очень хороших функциональных возможностей, которые большинство людей просто не используют, потому что они не проводили какое-либо время, изучая его.

+0

Приобретено. Получены ли какие-либо URL-адреса для веб-страниц/учебных пособий, которые охватывают возможности MVC, которые большинство людей пропустили (например, атрибут DataType)? –

+1

@RobertOschler - http://channel9.msdn.com/Events/aspConf/aspConf/ASP-NET-MVC-Tips-Tricks-and-Hidden-Gems –

+0

Спасибо за ссылку на видео. –