Pull to refresh

Declarative HTML Helpers

Reading time3 min
Views14K

@functions @helpers


Большинство хелперов в asp.net mvc 3 это методы-расширения класса System.Web.Mvc.HtmlHelper.
Однако не всегда удобно создавать отдельный статический класс для 2-3 хелперов необходимых в одной вьюшке. И совсем неудобно создавать хелперы возвращающие большие блоки html-кода: ни подсветки синтаксиса, ни интеллисенса, ни прочих плюшек.

Для решения этих проблем в Razor есть два замечательных блока. Они позволяют создавать хелперы непосредственно в .cshtml-файлах.

image

Блок @functions

Razor-страничка это класс, наследуемый от System.Web.Mvc.WebViewPage<TModel>. Обычно используется только его метод void Execute(), который и генерирует html-код

Блок @functions позволяет добавить свои методы, свойства, поля и т.д.

@functions
{
    string HelloWorld()
    {
      return "Hello world";
    }
    string Now
    {
      get { return DateTime.Now.ToString("dd MMMM"); }
    }
    
    class SomeClass
    {
      ...
    }
}


Такой подход может сильно упросить код. Допустим у нас есть некий enum:

enum State
{
    Created,
    ProcessingStage1,
    ProcessingStage2,
    Accepted,
    Rejected
}


и в зависимости от статуса нам нужны разные картинки и цвет рамки:

@functions
{
  enum State
  {
    Created,
    ProcessingStage1,
    ProcessingStage2,
    Accepted,
    Rejected
  }
  
  string GetStateImg(State state)
  {
    switch (state)
    {
      case State.Created:
        return "created.png";
      case State.ProcessingStage1:
      case State.ProcessingStage2:
        return "processing.png";
      case State.Accepted:
        return "accepted.png";
      case State.Rejected:
        return "rejected.png";
      default:
        return "";
    }
  }
  string GetStateBorderColor(State state)
  {
    switch (state)
    {
      case State.Accepted:
        return "green";
      case State.Rejected:
        return "red";
      default:
        return "yellow";
    }
  } 

  public static int SomeFunc(int a, int b)
  {
    return a + b;
  }

}


в результате получает возможность делать так:

<div class="border @(GetStateBorderColor(State.Accepted))">
  <img src="~/images/@(GetStateImg(State.Accepted))" />
  ...
</div>



Разумеется, методы GetStateImg и GetStateBorderColor можно было вынести куда-то в .cs код в какой-то хелпер-класс, но куда логичнее держать хелперы необходимые только одной вьюшке в этой же вьюшке.

Блок @helpers

У блока @functions есть небольшой недостаток: подразумеваются, что этот блок должен содержать обычные функции/свойства класса и, как следствие, нельзя вставлять html в тело функции пользуясь всеми радостями Razor.

Для этой задачи используется блок @helpers.
объявляем хелпер:

@helper Email(string address, string name = null)
{
  <a href="mailto:@(address)">@(name ?? address)</a>  
}


и используем @Email("google@gmail.ru")

И самое замечательное

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

@Helpers.Email("some state")


P.S разумеется, методы должны быть public и static, чтобы можно было использовать их из других классов
Tags:
Hubs:
Total votes 42: ↑37 and ↓5+32
Comments12

Articles