加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-core – 如何将在TagHelper流程方法中生成的脚本渲染到

发布时间:2020-12-16 07:20:16 所属栏目:asp.Net 来源:网络整理
导读:我在TagHelper类的进程方法中生成脚本如下 [TargetElement("MyTag")] public Class MYClass: TagHelper{ public override void Process(TagHelperContext context,TagHelperOutput output) {StringBuilder builder = new StringBuilder(); builder.Append("s
我在TagHelper类的进程方法中生成脚本如下

[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());
}
}

现在它将脚本放在标签元素旁边作为其兄弟.

我需要将脚本放在body部分的末尾.

解决方法

我创建了一对能够解决问题的自定义标记帮助程序.

第一个是< storecontent>它只是将包含在其中的html内容存储在TempData字典中.它不提供直接输出.内容可以是内联脚本或任何其他html.许多这种标签帮助器可以放置在不同的位置,例如在部分视图中.

第二个标签助手是< renderstoredcontent>并且它将所有先前存储的内容呈现在期望的位置,例如在主体元素的末尾.

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

基本用法:

在某些视图或部分视图中:

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

在另一个位置:

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

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

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

而已.

几点说明:

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

< renderstoredcontent asp-key =“scripts”>< / renderstoredcontent>

另一组“脚注”可以在另一个位置呈现.

>< storecontent>必须在< renderstoredcontent>之前定义被申请;被应用.在ASP.NET中,响应以反向层次顺序生成,首先生成最内部的部分视图,然后是父部分视图,然后是主视图,最后是布局页面.因此,您可以轻松地使用这些标记帮助程序在局部视图中定义脚本,然后在布局页面的正文部分末尾呈现脚本.
>不要忘记使用命令@addTagHelper“*,YourProjectHere”在_ViewImports.cshtml文件中引用自定义标记助手.

对不起,很长的帖子,我希望它有所帮助!

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读