gpt4 book ai didi

asp.net-core - 如何将 TagHelper 处理方法中生成的脚本渲染到页面底部而不是标签元素旁边?

转载 作者:行者123 更新时间:2023-12-02 05:12:17 27 4
gpt4 key购买 nike

我在 TagHelper 类的 process 方法中生成脚本,如下所示

[TargetElement("MyTag")]
public Class MYClass: TagHelper{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
StringBuilder builder = new StringBuilder();

builder.Append("<script>");
builder.Append("//some javascript codes here);
builder.Append("</script>");
output.Content.Append(builder.ToString());
}
}

现在,它将脚本放置在标签元素的旁边,作为其同级元素。

我需要将脚本放在正文部分的末尾。

最佳答案

我创建了一对自定义标签助手,可以解决您的问题。

第一个是<storecontent>它只是将包裹在其中的 html 内容存储在 TempData 字典中。它不提供直接输出。内容可以是内联脚本或任何其他 html。许多这种类型的标签助手可以放置在不同的位置,例如在局部 View 中。

第二个标签助手是 <renderstoredcontent>并将所有先前存储的内容呈现在所需的位置,例如在 body 元素的末尾。

代码 StoreContentTagHelper.cs :

using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;


namespace YourProjectHere.TagHelpers
{
[TargetElement("storecontent", Attributes = KeyAttributeName)]
public class StoreContentTagHelper : TagHelper
{
private const string KeyAttributeName = "asp-key";
private const string _storageKey = "storecontent";
private const string _defaultListKey = "DefaultKey";

[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }

[HtmlAttributeName(KeyAttributeName)]
public string Key { get; set; }

public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
output.SuppressOutput();
TagHelperContent childContent = await context.GetChildContentAsync();

var storageProvider = ViewContext.TempData;
Dictionary<string, List<HtmlString>> storage;
List<HtmlString> defaultList;

if (!storageProvider.ContainsKey(_storageKey) || !(storageProvider[_storageKey] is Dictionary<string,List<HtmlString>>))
{
storage = new Dictionary<string, List<HtmlString>>();
storageProvider[_storageKey] = storage;
defaultList = new List<HtmlString>();
storage.Add(_defaultListKey, defaultList);
}
else
{
storage = ViewContext.TempData[_storageKey] as Dictionary<string, List<HtmlString>>;
if (storage.ContainsKey(_defaultListKey))
{
defaultList = storage[_defaultListKey];

}
else
{
defaultList = new List<HtmlString>();
storage.Add(_defaultListKey, defaultList);
}
}

if (String.IsNullOrEmpty(Key))
{
defaultList.Add(new HtmlString(childContent.GetContent()));
}
else
{
if(storage.ContainsKey(Key))
{
storage[Key].Add(new HtmlString(childContent.GetContent()));
}
else
{
storage.Add(Key, new List<HtmlString>() { new HtmlString(childContent.GetContent()) });
}
}
}
}
}

代码 RenderStoredContentTagHelper.cs :

using System;
using System.Linq;
using System.Collections.Generic;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Mvc.Rendering;
using Microsoft.AspNet.Razor.Runtime.TagHelpers;


namespace YourProjectHere.TagHelpers
{
[TargetElement("renderstoredcontent", Attributes = KeyAttributeName)]
public class RenderStoredContentTagHelper : TagHelper
{
private const string KeyAttributeName = "asp-key";
private const string _storageKey = "storecontent";

[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }

[HtmlAttributeName(KeyAttributeName)]
public string Key { get; set; }

public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = String.Empty;

var storageProvider = ViewContext.TempData;
Dictionary<string, List<HtmlString>> storage;

if (!storageProvider.ContainsKey(_storageKey) || !(storageProvider[_storageKey] is Dictionary<string, List<HtmlString>>))
{
return;
}

storage = storageProvider[_storageKey] as Dictionary<string, List<HtmlString>>;
string html = "";

if (String.IsNullOrEmpty(Key))
{
html = String.Join("", storage.Values.SelectMany(x => x).ToList());
}
else
{
if (!storage.ContainsKey(Key)) return;
html = String.Join("", storage[Key]);
}

TagBuilder tagBuilder = new TagBuilder("dummy");
tagBuilder.InnerHtml = html;
output.Content.SetContent(tagBuilder.InnerHtml);
}
}
}

基本用法:

在某些 View 或部分 View 中:

<storecontent asp-key="">
<script>
your inline script...
</script>
</storecontent>

在另一个位置:

<storecontent asp-key="">
<script src="..."></script>
</storecontent>

最后在应该呈现两个脚本的所需位置:

<renderstoredcontent asp-key=""></renderstoredcontent>

就是这样。

一些注意事项:

  1. 可以有任意数量的 <storecontent>标签。 asp-key属性是必需的,至少为空“”。如果您为此属性指定特定值,则可以对存储的内容进行分组并在不同位置呈现特定组。例如。如果您使用 asp-key="scripts" 指定一些内容以及其他一些内容 asp-key="footnotes"那么您可以使用以下方法仅将第一组渲染为某个位置:

<renderstoredcontent asp-key="scripts"></renderstoredcontent>

另一组“脚注”可以在其他位置呈现。

  • <storecontent>必须在 <renderstoredcontent> 之前定义被申请;被应用。在 ASP.NET 中,响应是以相反的层次顺序生成的,首先生成最里面的部分 View ,然后是父部分 View ,然后是主视图,最后是布局页面。因此,您可以轻松地使用这些标签助手在分部 View 中定义脚本,然后在布局页面中的正文部分的末尾呈现脚本。

  • 不要忘记使用命令 @addTagHelper "*, YourProjectHere" 在 _ViewImports.cshtml 文件中引用自定义标记助手。

  • 很抱歉这篇文章很长,希望对您有所帮助!

    关于asp.net-core - 如何将 TagHelper 处理方法中生成的脚本渲染到页面底部而不是标签元素旁边?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31313529/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com