我想在我的MVC视图中将自定义渲染器定义为lambda,我可以在局部使用它来多次渲染相同的东西。我打算将它存储在视图数据中。到目前为止,我已经创建了这个扩展方法来存储渲染器:
public static class HtmlHelperExtensions
{
public static void DefineRenderer<TModel>(this HtmlHelper<TModel> html, string rendererName, Action renderer)
{
html.ViewData["_Renderer" + rendererName] = renderer;
}
}
我正在尝试在我的视图中定义渲染器,但它无法正常工作;我假设我的语法已关闭。有人能告诉我这里我做错了什么吗?我只是希望它在调用时呈现测试段落:
@Html.DefineRenderer("AnalysisTableHeader", () => {
<p>test paragraph</p>
@});
答案 0 :(得分:1)
DefineRenderer
- 方法需要返回除void之外的任何内容,例如IHtmlString
使用剃刀@
- 语法调用它,否则您需要像这样调用它:
@{
Html.DefineRenderer("AnalysisTableHeader", () => {
<p>test paragraph</p>
});
}
编辑:抱歉,我看到renderer
参数的类型为System.Action
。我认为它必须是System.Func<dynamic, HelperResult>
类型,你需要调用它
@{ Html.DefineRenderer("AnalysisTableHeader", @<text><p>test paragraph</p></text>); }
例如,。然后,您可以像这样呈现它:render(null).ToHtmlString()
。无论如何要注意,如果你在视图中做这样的事情,你可能会遇到部分视图缓存的问题。
答案 1 :(得分:0)
我仍然不能100%确定这是否是你所需要的,但也许它会有所帮助。 在部分视图中定义@helper,并根据Model中的值决定要呈现的版本:
在代码中使用标题类型声明枚举
public enum HeaderTypes
{
AnalysisTable,
SomethingElse
}
然后在你看来
@helper RenderHeader(HeaderTypes headerType) {
switch (headerType)
{
case HeaderTypes.AnalysisTable:
@: <p>your html</p>
break;
default:
@: <p>default</p>
break;
}
}
@RenderHeader(HeaderTypes.None)
@RenderHeader(HeaderTypes.AnalysisTable)
或者您可以根据字符串值或其他内容进行切换。
答案 2 :(得分:0)
从@ mariozski的评论中得到一些灵感,我设法得到了我想要的行为。我使用@helper
作为渲染器。传递给partial的模型包含辅助渲染的结果,即。一个HelperResult
。所以它看起来像这样:
public class AnalysisResponseTableViewModel {
public HelperResult HeaderTypeRowRenderer { get; set; }
public List<AnalysisUserResponseViewModel> Responses { get; set; }
}
然后,调用视图调用部分如下:
@helper RenderHeaderTypeRow() {
<tr class="headerTypeRow">
<td>Header type row</td>
<td>Goes here</td>
</tr>
}
@Html.Partial("AnalysisResponseTableContentsPartial",
new AnalysisResponseTableViewModel {
Responses = Model.OverallCaseStudyUserResponses,
HeaderTypeRowRenderer = RenderHeaderTypeRow()
}
)
最后,部分本身可以像这样多次呈现'标题类型行':
@Html.Raw(Model.HeaderTypeRowRenderer.ToHtmlString())
@{bool reachedSummaryRows = false;}
@foreach (var response in Model.Responses) {
if (!reachedSummaryRows && !response.IsPass.HasValue) {
reachedSummaryRows = true;
@:@Html.Raw(Model.HeaderTypeRowRenderer.ToHtmlString())
}
// other table rows here
}