我有一个Razor辅助函数,可以创建一个可重复使用的HTML面板,可以让我一遍又一遍地编写相同的HTML。
@helper DefaultPanel(string panelTitle) {
<div class="panel">
<div class="panel-logo"><img src="/logo.png"></div>
<div class=panel-inner">
<p class="panel-title">@panelTitle</p>
<div class="panel-content">
/* Can I pass content to be rendered in here here? */
</div>
</div>
</div>
</div>
}
我想知道,是否有可能重新使用此帮助程序为.panel-content
填充更多HTML以允许进一步的灵活性和代码重用 - 类似如下所示:
@LayoutHelpers.DefaultPanel("Welcome back") {
<div class="panel-content-inner">
<p>Welcome back, please select from the following options</p>
<a href="#">Profile</a>
<a href="#">My Defails</a>
</div>
}
虽然使用.NET MVC我注意到Html.BeginForm()
在@using
声明中的Html.BeginForm
语句中包装代码时做了类似的事情,如下所示:
@using (Html.BeginForm("Index", "Login", FormMethod.Post))
{
<div>This content gets rendered within the <form></form> markup.</div>
}
但这可以使用@helper
方法完成吗?如果没有,是否可以创建HtmlHelper
扩展程序来执行与Html.BeginForm()
方法相似的操作?
您可以使用@section
这似乎是能够做到的事情非常有用的事情,并且奇怪的是,在组件级别上没有简单的方法。
答案 0 :(得分:38)
有两种方法可以实现所需的功能。
<强> 1。 @helper 强>
创建@helper,它接受你需要的任何参数以及一个函数(单个对象参数,返回对象):
@helper DefaultPanel(string panelTitle, Func<object, object> content)
{
<div class="panel">
<div class="panel-logo">
<img src="/logo.png" />
</div>
<div class="panel-inner">
<p class="panel-title">@panelTitle</p>
<div class="panel-content">
@content(null)
</div>
</div>
</div>
}
用法:
@DefaultPanel("title",
@<div class="panel-content-inner">
<p>Welcome back, please select from the following options</p>
<a href="#">Profile</a>
<a href="#">My Defails</a>
</div>
)
您的功能也可以接受参数,例如here。
<强> 2。 HtmlHelper扩展方法
在项目的任何位置添加以下代码:
namespace System.Web.Mvc
{
public static class HtmlHelperExtensions
{
public static HtmlDefaultPanel DefaultPanel(this HtmlHelper html, string title)
{
html.ViewContext.Writer.Write(
"<div class=\"panel\">" +
"<div class=\"panel-inner\">" +
"<p class=\"panel-title\">" + title + "</p>" +
"<div class=\"panel-content\">"
);
return new HtmlDefaultPanel(html.ViewContext);
}
}
public class HtmlDefaultPanel : IDisposable
{
private readonly ViewContext _viewContext;
public HtmlDefaultPanel(ViewContext viewContext)
{
_viewContext = viewContext;
}
public void Dispose()
{
_viewContext.Writer.Write(
"</div>" +
"</div>" +
"</div>"
);
}
}
}
用法:
@using (Html.DefaultPanel("title2"))
{
<div class="panel-content-inner">
<p>Welcome back, please select from the following options</p>
<a href="#">Profile</a>
<a href="#">My Defails</a>
</div>
}
扩展方法直接写入上下文。诀窍是返回一个一次性对象,Dispose方法将在using
块结束时执行。
答案 1 :(得分:1)
我不知道@helper
方法是否可以执行此操作,但HtmlHelper
扩展当然可以。您已经提到了可能是最知名的Html.BeginForm()
示例 - 所有这一切都返回一个实现IDisposable
的对象,这意味着当调用Dispose()
方法时它只是调用免费的Html.EndForm()
方法来添加适当的结束标记。
为HTML代码执行类似的操作非常简单。您可以在http://aspnetwebstack.codeplex.com/查看ASP.NET MVC HtmlHelpers的源代码 - BeginForm()
代码可以是viewed here。