我正在尝试在ASP.NET MVC中创建一个可重用的UI元素,它包含我选择放入其中的任何内容。我的第一个想法是创建一个局部视图,但这似乎并没有帮助我实现我想要完成的任务。
例如,我想创建一些与此类似的可重用标记(请原谅伪代码):
<div class="panel panel-default">
<div class="panel-body">
@RenderBody()
</div>
</div>
然后在我看来,我想做类似的事情:
@Render.Partial("MyPanel")
{
<img src="image.jpg" />
}
假设代码按预期工作,它将生成以下内容:
<div class="panel panel-default">
<div class="panel-body">
<img src="image.jpg" />
</div>
</div>
从理论上讲,我希望能够在其中一个面板中放置任何我想要的东西。因此,更复杂的标记仍然显得清晰可见。
@Render.Partial("MyPanel")
{
<form>
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
</div>
<div class="form-group">
<label for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
</div>
<div class="form-group">
<label for="exampleInputFile">File input</label>
<input type="file" id="exampleInputFile">
<p class="help-block">Example block-level help text here.</p>
</div>
<div class="checkbox">
<label>
<input type="checkbox"> Check me out
</label>
</div>
<button type="submit" class="btn btn-default">Submit</button>
</form>
}
就像在第一个例子中一样,它会将所有内容包装在我的模板的页眉和页脚中:
<div class="panel panel-default">
<div class="panel-body">
<form>
<div class="form-group">
<label for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
</div>
.. truncated ..
<button type="submit" class="btn btn-default">Submit</button>
</form>
</div>
</div>
我可以通过创建自定义控件在ASP.NET WebForms中执行此操作。看起来这在MVC中应该是直截了当的,但我还没有能够找到一个好的解决方案。
答案 0 :(得分:2)
您可以使用&#34; DynamicInvoke&#34;使用动态标记创建html助手,例如:
public static IHtmlString CustomPanel(this HtmlHelper htmlHelper, Func<object, object> panelMarkup = null)
{
return CustomPanel(htmlHelper, (panelMarkup == null ? "" : panelMarkup.DynamicInvoke(htmlHelper.ViewContext).ToString()));
}
public static IHtmlString CustomPanel(this HtmlHelper htmlHelper, string content)
{
TagBuilder div = new TagBuilder("div");
div.AddCssClass("panel panel-default");
TagBuilder innerDiv = new TagBuilder("div");
innerDiv.AddCssClass("panel-body");
innerDiv.InnerHtml = content;
div.InnerHtml = innerDiv.ToString();
return new HtmlString(div.ToString());
}
然后你会像这样使用它:
@Html.CustomPanel(
@<text>
<div>My Custom Markup</div>
<span>More Stuff</span>
</text>
)
您的最终内容如下:
<div class="panel panel-default">
<div class="panel-body">
<div>My Custom Markup</div>
<span>More Stuff</span>
</div>
</div>
你看到这在一些第三方小部件库中经常使用(kendo-ui是我所知道的主要部分)
答案 1 :(得分:0)
有许多方法可以在MVC中创建可重用的内容,但它们各有利弊。例如,自定义Html帮助程序是一种常见方法,但它们需要编写比您可能想要的代码更多的代码。
你当然可以使用局部视图,只需将包含你要渲染的内容的模型传递给局部视图......但这也可能有点令人困惑。
我认为你可能正在寻找的是Razor Helpers。这些在这里有更详细的解释:
http://weblogs.asp.net/scottgu/asp-net-mvc-3-and-the-helper-syntax-within-razor
但是,基本结构如下所示:
@helper MyHelper(string content)
{
<div class="panel panel-default">
<div class="panel-body">
@Html.Raw(content)
</div>
</div>
}
然后你就这样使用它:
@MyHelper("<img src="image.jpg" />")
您不必使用字符串,您可以使用结构化内容,模型等。您可以在其中使用其他帮助程序。您可以按照本文后面的描述重复使用它们。
但是,您可能希望开始将您的网页视为更加以数据为中心。如果您使用EditorTemplates渲染数据,那么您将根据数据类型呈现控件,而不是渲染页面并尝试调整页面以包含数据。