在ASP.NET MVC中使用Razor创建可重用的HTML视图组件

我有一个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内容与更多的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()在Html.BeginForm声明中的@using语句中包装代码时也是类似的,像这样:

@using (Html.BeginForm("Index","Login",FormMethod.Post))
{
    <div>This content gets rendered within the <form></form> markup.</div>
}

但是可以使用@helper方法吗?如果没有,是否可以创建一个HtmlHelper扩展来做类似的事情,Html.BeginForm()方法的方式?

你可以使用@section语法来做一个非常相似的事情,如here所示

这似乎是能够做到真正有用的东西,奇怪的是在组件级别上没有简单的方法来做到这一点。

解决方法

有两种方法来实现所需的功能

@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方法将在使用结束时执行。

相关文章

### 创建一个gRPC服务项目(grpc服务端)和一个 webapi项目(...
一、SiganlR 使用的协议类型 1.websocket即时通讯协议 2.Ser...
.Net 6 WebApi 项目 在Linux系统上 打包成Docker镜像,发布为...
一、 PD简介PowerDesigner 是一个集所有现代建模技术于一身的...
一、存储过程 存储过程就像数据库中运行的方法(函数) 优点:...
一、Ueditor的下载 1、百度编辑器下载地址:http://ueditor....