MVC:读取自定义 HTML 帮助程序中的内容
本文关键字:帮助程序 HTML 读取 自定义 MVC | 更新日期: 2023-09-27 18:25:53
我正在尝试构建一个有条件地修改其内容的HTML助手。原因是我可以将内容移动到页面的另一部分(在母版页和子视图的上下文中(或在某些情况下完全删除它们。
例如,我可能有一些 JavaScript 我希望移动到其他地方(请记住,section
对象仅在视图直接引用托管该命名部分的页面时才有效(,或者如果我希望使用模块命名空间限定一些 JavaScript 调用。
我在构建构成 HTML 助手主要部分的IDisposable
方面没有问题,并且我知道如何将内容写入页面的输出,但我无法弄清楚如何阅读内容。
例如,如果我的 Razor 视图上有这个:
@using (Html.MyHtmlHelper())
{
<div>hello world</div>
}
然后有
private static IDisposable MyHtmlHelper(this HtmlHelper htmlHelper)
{
// ...
}
在该静态帮助程序方法中,我需要什么来检索<div>hello world</div>
内容?
您可以在初始化帮助程序时调用此代码:
var strContents = new HtmlTextWriter(htmlHelper.ViewContext.Writer).InnerWriter.ToString();
获取上下文中的当前字符串。
然后在释放此控件时比较相同代码的结果,以获取帮助程序内的内容。
这似乎是一种奇怪的方法,可能有更有效的替代解决方案。一个观察:使用中的所有内容在视图中都是静态的(硬编码(。 这意味着必须有其他外部变量影响渲染的内容,因为视图中的内容不是动态的。 <div>My div</div>
永远不会改变,那么可以对它执行什么类型的逻辑,并不总是导致同样的事情?
我将介绍一个原因(可能还有更多(,然后提出另一种解决方案。
为什么?
请考虑以下示例:
@using(Html.MyHtmlHelper()) {
<div>Normal Text, no problem in theory</div>
<span>@Model.MyCustomContent</span>
}
在这种情况下,@Model 是一个动态值,直到运行时才知道,并且仅用作某些服务器端值的占位符,以便在调用整个 MVC 管道后替换为实际内容(这将在调用帮助程序后发生(。 在这种情况下,帮助程序应该怎么做? 它无法识别@Model(或MyCustomContent(是什么。 此外,在这种情况下,使用中的条件逻辑和/或循环也会带来挑战。
也许更成问题的(出于类似的原因(,会是这样的:
@using(Html.MyHtmlHelper()) {
<div>Normal Text, no problem in theory</div>
<span>@Model.MyCustomContent</span>
@using(Html.MyHtmlHelper()) {
<div>More nested custom stuff</div>
}
}
在这种情况下,我们想要的是让内部 using 首先执行,渲染一个字符串输出,然后让外部 using 执行,使用内部 using 渲染的输出,但这不是代码的执行方式。
另一种选择:
相反,请考虑将要有条件呈现的内容放在单独的分部视图中:
//MyPartialView.cshtml
<div>Hello World</div>
@Model.CustomContent
<div>Dynamic Switcheroo</div>
然后你可以在你的主视图中说:
@Html.MyHtmlHelper("MyPartialView", Model)
在扩展方法中:
private static HtmlString MyHtmlHelper(this HtmlHelper htmlHelper, string viewName, object model)
{
string output = htmlHelper.Partial(viewName, model).ToHtmlString();
//TODO: Conditional string parsing based on output
string formattedOutput = output.SomeOperation();
return new HtmlString(formattedOutput);
}
第二种选择:
如果需要,可以使用模型或上下文的属性来确定在何处以及何时呈现的内容。
如果您有视图模型:
public class ConditionalRenderingViewModel {
public bool ShouldRenderJavascript {get; set;}
}
然后,在您看来:
@Html.MyHtmlHelper(Model)
然后,在您的 HTML 帮助程序中
public static HtmlString MyHtmlHelper(ConditionalRenderingViewModel model) {
if(model.ShouldRenderJavascript) {
return new HtmlString("<script type='text/javascript' src='customjs.js'></script>");
} else {
return new HtmlString("");
}
}
这使您能够控制输出,而无需分析文本或依赖硬编码的视图标记。
您可以在此处查看一些其他策略:http://www.codemag.com/Article/1312081