在 ASP.NET Core MVC 中嵌套 TagHelper [英] Nesting TagHelpers in ASP.NET Core MVC

查看:26
本文介绍了在 ASP.NET Core MVC 中嵌套 TagHelper的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

ASP.NET Core TagHelper 文档 给出以下示例:

public class WebsiteContext{公共版本版本{获取;放;}public int CopyrightYear { get;放;}公共布尔批准{得到;放;}公共 int TagsToShow { 获取;放;}}[TargetElement("网站信息")]公共类 WebsiteInformationTagHelper : TagHelper{公共网站上下文信息 { 获取;放;}公共覆盖无效流程(TagHelperContext 上下文,TagHelperOutput 输出){output.TagName = "节";output.Content.SetContent($@"<ul><li><strong>版本:</strong> {Info.Version}</li><li><strong>版权年份:</strong>{Info.CopyrightYear}</li><li><strong>批准:</strong>{Info.Approved}<li><strong>要显示的标签数量:</strong>{Info.TagsToShow}</li></ul>");output.TagMode = TagMode.StartTagAndEndTag;}}

这可以在您的 Razor .cshtml 中使用,如下所示:

这将生成以下 HTML:

<ul><li><strong>版本:</strong>1.3 升<li><strong>版权年份:</strong>1790 升<li><strong>批准:</strong>真<li><strong>要显示的标签数量:</strong>第131话</节>

这是非常丑陋的标签助手语法.有什么方法可以嵌套另一个标签助手并获得完整的智能感知,以便网站信息的唯一允许子项可以是上下文?请参见下面的示例:

<context version="1.3" copyright="1790" 批准 tags-to-show="131"/></网站信息>

在我的用例中,网站信息元素已经有很多属性,我想添加一个或多个单独的嵌套元素.

更新

我在 ASP.NET GitHub 页面上提出了this 建议以实现此功能用于 TagHelper.

解决方案

您当然可以嵌套标记助手,尽管其他选项(如视图组件、部分视图或显示模板)可能更适合 OP 描述的场景.

这可能是一个非常简单的标签助手:

[HtmlTargetElement("child-tag", ParentTag="parent-tag")]公共类 ChildTagHelper : TagHelper{公共字符串消息 { 获取;放;}公共覆盖无效流程(TagHelperContext 上下文,TagHelperOutput 输出){//创建父divoutput.TagName = "span";output.Content.SetContent(Message);output.TagMode = TagMode.StartTagAndEndTag;}}

这也可以是另一个简单的标签助手:

[HtmlTargetElement("parent-tag")][RestrictChildren("child-tag")]公共类ParentTagHelper:TagHelper{公共字符串标题{获取;放;}公共覆盖异步任务 ProcessAsync(TagHelperContext 上下文,TagHelperOutput 输出){output.TagName = "div";//添加一些特定的父助手 htmlvar header = new TagBuilder("h1");header.Attributes.Add("class", "parent-title");header.InnerHtml.Append(this.Title);output.PreContent.SetContent(header);//设置这个助手的内部内容(将处理任何嵌套的标签助手或任何其他剃刀代码)output.Content.SetContent(await output.GetChildContentAsync());}}

在剃刀视图中,您可以编写以下内容:

<child-tag message="这是嵌套标签助手"/></parent-tag>

将呈现为:

<h1 class="parent-title">我的标题</h1><span>这是嵌套标签助手</span>

您可以可选地强制以特定方式嵌套标签助手:

  • 在父标签助手中使用 [RestrictChildren("child-tag", "another-tag")] 来限制允许的嵌套标签助手
  • 在声明子标签助手时使用 ParentTag 参数来强制将标签嵌套在特定的父标签中 [HtmlTargetElement("child-tag", ParentTag = "parent-tag")]

The ASP.NET Core TagHelper documentation gives the following example:

public class WebsiteContext
{
    public Version Version { get; set; }
    public int CopyrightYear { get; set; }
    public bool Approved { get; set; }
    public int TagsToShow { get; set; }
}

[TargetElement("website-information")]
public class WebsiteInformationTagHelper : TagHelper
{
    public WebsiteContext Info { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.TagName = "section";
        output.Content.SetContent(
            $@"<ul><li><strong>Version:</strong> {Info.Version}</li>
            <li><strong>Copyright Year:</strong> {Info.CopyrightYear}</li>
            <li><strong>Approved:</strong> {Info.Approved}</li>
            <li><strong>Number of tags to show:</strong> {Info.TagsToShow}</li></ul>");
        output.TagMode = TagMode.StartTagAndEndTag;
    }
}

This can then be used in your Razor .cshtml as follows:

<website-information info="new WebsiteContext {
    Version = new Version(1, 3),
    CopyrightYear = 1790,
    Approved = true,
    TagsToShow = 131 }"/>

This will generate the following HTML:

<section>
    <ul>
        <li><strong>Version:</strong> 1.3</li>
        <li><strong>Copyright Year:</strong> 1790</li>
        <li><strong>Approved:</strong> true</li>
        <li><strong>Number of tags to show:</strong> 131 </li>
    </ul>
</section>

This is pretty ugly tag helper syntax. Is there some way to nest another tag helper and get full intelli-sense so that the only allowed child of website-information can be context? See example below:

<website-information>
    <context version="1.3" copyright="1790" approved tags-to-show="131"/>
</website-information>

In my use case, the website-information element already has many attributes and I want to add one or more separate nested elements.

UPDATE

I have raised this suggestion on the ASP.NET GitHub page to implement this feature for TagHelpers.

解决方案

You can certainly nest tag helpers, although maybe other options like view components, partial views or display templates might be better suited for the scenario described by the OP.

This could be a very simple child tag helper:

[HtmlTargetElement("child-tag", ParentTag="parent-tag")]
public class ChildTagHelper : TagHelper
{
    public string Message { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        // Create parent div
        output.TagName = "span";
        output.Content.SetContent(Message);
        output.TagMode = TagMode.StartTagAndEndTag;     
    }
}

And this could also be another simple parent tag helper:

[HtmlTargetElement("parent-tag")]
[RestrictChildren("child-tag")]
public class ParentTagHelper: TagHelper
{
    public string Title { get; set; }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {            
        output.TagName = "div";

        // Add some specific parent helper html
        var header = new TagBuilder("h1");
        header.Attributes.Add("class", "parent-title");
        header.InnerHtml.Append(this.Title);
        output.PreContent.SetContent(header);

        // Set the inner contents of this helper(Will process any nested tag helpers or any other piece of razor code)
        output.Content.SetContent(await output.GetChildContentAsync());            
    }
}

In a razor view you could then write the following:

<parent-tag title="My Title">
    <child-tag message="This is the nested tag helper" />
</parent-tag>

Which would be rendered as:

<div>
    <h1 class="parent-title">My Title</h1>
    <span>This is the nested tag helper</span>
</div>

You can optionally enforce tag helpers to be nested in a particular way:

  • Use [RestrictChildren("child-tag", "another-tag")] in the parent tag helper to limit the allowed nested tag helpers
  • Use the ParentTag parameter when declaring the child tag helper to enforce the tag being nested inside a particular parent tag [HtmlTargetElement("child-tag", ParentTag = "parent-tag")]

这篇关于在 ASP.NET Core MVC 中嵌套 TagHelper的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆