在 ASP.NET MVC 中使用 Razor 创建可重用的 HTML 视图组件 [英] Creating reusable HTML view components using Razor in ASP.NET MVC

查看:17
本文介绍了在 ASP.NET MVC 中使用 Razor 创建可重用的 HTML 视图组件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Razor 辅助函数,它创建了一个可重复使用的 HTML 面板,从而节省了我一遍又一遍地编写相同的 HTML.

@helper DefaultPanel(string panelTitle) {<div class="面板"><div class="panel-logo"><img src="/logo.png"></div><div class=panel-inner"><p class="panel-title">@panelTitle</p><div class="panel-content">/* 我可以在这里传递要渲染的内容吗?*/

}

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

@LayoutHelpers.DefaultPanel("欢迎回来") {<div class="panel-content-inner"><p>欢迎回来,请从以下选项中选择</p><a href="#">个人资料</a><a href="#">我的失败</a>

}

在使用 .NET MVC 时,我注意到 Html.BeginForm() 在将代码包装在 @using 语句中时做了类似的事情 Html.BeginForm 声明,像这样:

@using (Html.BeginForm("Index", "Login", FormMethod.Post)){<div>此内容在 <form></form> 中呈现.标记.

}

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

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

2.HtmlHelper 扩展方法

在项目中的任意位置添加以下代码:

命名空间 System.Web.Mvc{公共静态类 HtmlHelperExtensions{public static HtmlDefaultPanel DefaultPanel(this HtmlHelper html, string title){html.ViewContext.Writer.Write("<div class="面板">"+"<div class="panel-inner">"+"<p class="面板标题">"+ 标题 + "</p>"+"<div class="panel-content">");返回新的 HtmlDefaultPanel(html.ViewContext);}}公共类 HtmlDefaultPanel : IDisposable{私有只读 ViewContext _viewContext;公共 HtmlDefaultPanel(ViewContext viewContext){_viewContext = 视图上下文;}公共无效处置(){_viewContext.Writer.Write(</div>"+</div>"+</div>");}}}

用法:

@using (Html.DefaultPanel("title2")){<div class="panel-content-inner"><p>欢迎回来,请从以下选项中选择</p><a href="#">个人资料</a><a href="#">我的失败</a>

}

扩展方法直接写入上下文.诀窍是返回一个一次性对象,该 Dispose 方法将在 using 块的末尾执行.

I have a Razor helper function that creates a re-usable HTML panel that saves me writing the same HTML over and over again.

@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>
}

I'm wondering, is it possible to re-use this helper to fill .panel-content with more HTML to allow further flexibility and code reuse - similar to something like below:

@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>
}

Whilst using .NET MVC I've noticed the Html.BeginForm() does a similar thing when wrapping the code within the @using statement within the Html.BeginForm declaration, like so:

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

But can this done using @helper methods? If not, is it possible to create a HtmlHelper extension to do a similar thing the way the Html.BeginForm() method does?

You can do a very similar thing using the @section syntax as seen here

This seems like something that would be really useful to be able to do, and odd that there's no easy way to do it on a component level.

解决方案

There are two ways to achieve the required functionality.

1. @helper

Create @helper which accepts whatever parameters you need plus a function (single object parameter, returns object):

@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>
}

Usage:

@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>
)

Your function may also accepts parameters, example here.

2. HtmlHelper extension method

Add the following code anywhere in your project:

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>"
            );
        }
    }
}

Usage:

@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>
}

The extension method writes directly to the context. The trick is to return a disposable object, which Dispose method will be executed at the end of using block.

这篇关于在 ASP.NET MVC 中使用 Razor 创建可重用的 HTML 视图组件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
C#/.NET最新文章
热门教程
热门工具
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆