【问题标题】:Creating reusable HTML view components using Razor in ASP.NET MVC在 ASP.NET MVC 中使用 Razor 创建可重用的 HTML 视图组件
【发布时间】:2014-05-07 12:57:39
【问题描述】:

我有一个 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>
}

我想知道,是否可以重新使用这个帮助程序来用更多的 HTML 填充 .panel-content 以允许进一步的灵活性和代码重用 - 类似于类似于以下内容:

@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() 在将代码包装在 @using 声明中的 Html.BeginForm 声明中时会执行类似的操作,如下所示:

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

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

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

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

【问题讨论】:

    标签: asp.net asp.net-mvc razor


    【解决方案1】:

    有两种方法可以实现所需的功能。

    1. @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 方法将在using 块的末尾执行。

    【讨论】:

    • 完美,第二个就像一个魅力!也感谢您花时间写出如此详尽的答案。
    • 由于某种原因,第二个代码 sn-p 给了我一个错误,“this”参数显然没有通过大括号中的 html
    【解决方案2】:

    我不知道@helper 方法是否可以做到这一点,但HtmlHelper 扩展当然可以。您提到了Html.BeginForm() 示例,这可能是最著名的示例 - 所做的只是返回一个实现IDisposable 的对象,这意味着当调用Dispose() 方法时,它只会调用免费的Html.EndForm() 方法来添加适当的结束标签。

    为您的 HTML 代码做类似的事情会非常简单。您可以在 http://aspnetwebstack.codeplex.com/ 查看 ASP.NET MVC HtmlHelpers 的源代码 - BeginForm() 代码可以具体为 viewed here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-10-15
      • 1970-01-01
      • 2011-10-09
      • 1970-01-01
      • 1970-01-01
      • 2015-07-07
      • 2011-12-17
      • 2011-09-02
      相关资源
      最近更新 更多