我甚至不确定这是否可行,但我想我会检查是否有办法让这更容易。
首先,我的网站中有一些重复的标记,如下所示:
<div class="module">
<h3>Title</h3>
<div>
<p>Information goes here</p>
</div>
</div>
我想要做的是将它包装在某种帮助器/部分中,以便我可以做这样的事情
@MyHelper("This is my Title") {
<p>Here is my custom markup</p>
}
然后,当它呈现时,它将注入通过<h3></h3>
和div中的自定义标记之间的参数传入的标题。自定义标记可以是从测试,表单控件到局部视图的任何内容。这是可能的吗?
答案 0 :(得分:15)
还有另一种方式,没有一次性技巧,这也需要少一点工作,非常适合小帮手。
@helper MyHelper(string title, Func<object, object> markup) {
<div class="module">
<h3>Title</h3>
<div>
<p>@markup.DynamicInvoke(this.ViewContext)</p>
</div>
</div>
}
这个助手的用法如下:
@MyHelper("This is my Title",
@<p>Here is my custom markup</p>
)
或多行:
@MyHelper("This is my Title",
@<text>
<p>More than one line</p>
<p>Of markup</p>
</text>
)
Telerik MVC控件使用这个技巧,例如让你在文档加载时添加你的javascript代码。
答案 1 :(得分:12)
嗯,这是使用HTML帮助扩展程序做一些接近它的“标准”方法。 Html.BeginForm()
所做的一个非常简单的版本。
方法:只需返回一个IDisposable,让using
语句处理其余的事情。
这只是概念的一个例子(尽管它有效)。不打算立即重复使用。使用大量快捷方式快速编写,而不是生产代码,大量改进和优化的机会,可能有愚蠢的错误,可以使用TagBuilder等。可以轻松修改以重用Wrapper类用于不同的...包装(甚至可能是一个已经在ASP.NET MVC中的通用 - 没有一个需要)。
public static class WrapHelper
{
private class Wrapper : IDisposable
{
private bool disposed;
private readonly TextWriter writer;
public Wrapper(HtmlHelper html)
{
this.writer = html.ViewContext.Writer;
}
public void Dispose()
{
if (disposed) return;
disposed = true;
writer.WriteLine(" </div>");
writer.WriteLine("</div>");
}
}
public static IDisposable Wrap(this HtmlHelper html, string title)
{
TextWriter writer = html.ViewContext.Writer;
writer.WriteLine("<div class=\"module\">");
writer.WriteLine(" <h3>" + html.Encode(title) + "</h3>");
writer.WriteLine(" <div>");
return new Wrapper(html);
}
}
用法:
@using (Html.Wrap("Title"))
{
<p>My very own markup.</p>
}
答案 2 :(得分:3)
@TheKaneda,感谢您的见解。我接受了你的想法并将其扩展,以便你提供一个PartialView名称,它知道如何解析它。
<Extension()> _
Public Function UseTemplate(ByVal html As HtmlHelper, ByVal PartialView As String) As IDisposable
Return New TemplateWrapper(html, PartialView)
End Function
Public Class TemplateWrapper
Implements IDisposable
Private _HtmlHelper As HtmlHelper
'Index 0 is header
'Index 1 is footer
Private _TemplateWrapper As String()
Public Sub New(ByVal Html As HtmlHelper, ByVal PartialView As String)
_TemplateWrapper = Html.Partial(PartialView).ToHtmlString.Split("@@RenderBody()")
_HtmlHelper = Html
_HtmlHelper.ViewContext.Writer.Write(_TemplateWrapper(0))
End Sub
Public Sub Dispose() Implements IDisposable.Dispose
_HtmlHelper.ViewContext.Writer.Write(_TemplateWrapper(1).Substring(12))
End Sub
End Class
使用与@ TheKaneda相同的用法。在部分视图中,不要调用@RenderBody(),只需将@@ RenderBody()作为内容中间部分的标志。对不起VB翻译。
使用我的用法示例。
Using Html.UseTemplate("ContentWrapper")
@Html.EditorFor(Function(m) m.Var1, "TemplateHint")
@Html.EditorFor(Function(m) m.Var2, "TemplateHint")
@Html.EditorFor(Function(m) m.Var3)
End Using
My Partial看起来像这样......
<div class="content">
@@RenderBody()
</div>
答案 3 :(得分:0)
如果您正在使用Razor和MVC 3,那么编写一个快速帮助方法就可以很容易地进入app_code文件夹,(我将其命名为MyHtmlHelpers)
我会尝试一些不同的东西,例如:
@helper myTemplate(string title, string markup){
<div class="module">
<h3>@title</h3>
@markup
</div>
}
从.cshtml文件中使用它的方式如下:
@MyHtmlHelpers.myTemplate('title','markup')
如果我理解正确,它应该有效。