zoukankan      html  css  js  c++  java
  • 【NetCore学习笔记之TagHelper】自定义自己的TagHelper

    自打Netcore推出以来,很多人是紧追不舍,关注度颇高,一时间让它成为了asp.net中的一等公民。我也是其中一份子,顶多算是一个伪粉丝吧,因为关注不太多,不够深。

    今天,主要记录的学习笔记是:如何自定义自己的Taghelper。话不多说,直入正题:

    1、定义接口

     public interface ICountryService
        {
            IEnumerable<CountryModel> GetAll();
        }

    2、定义接口实现类

     public class CountryService : ICountryService
        {
            private static IEnumerable<CountryModel> CountryList = new List<CountryModel>()
            {
                new CountryModel() { Id=1,enName="China",CnName="中国",Code="China"},
                new CountryModel() { Id=2,enName="Japan",CnName="日本",Code="Japan"},
                new CountryModel() { Id=3,enName="America",CnName="美国",Code="America"},
            };
            public IEnumerable<CountryModel> GetAll()
            {
                return CountryList;
            }
        }

    3、注入

      对于注入,多说几句。在.net core中,有几种常见注入方式:分别为(个人理解,不对的请大牛斧正):

      AddTransient: 每次请求ICountryService,就会生成一个对象;

      AddSingleton: 顾名思义,单例模式;贯穿整个application的生命周期,从Start--->End;

      AddScoped:可以理解为贯穿当前请求的整个生命周期。怎么理解呢,就是说当你第一次请求ICountryService的一个对象;在该请求的另外一个环节中,如果用到了ICountryService的其他逻辑,那么同样会共用第一次生成的对象。直到此次请求的生命周期结束。我个人认为,相当于生命周期内部的单例模式;

      

    public void ConfigureServices(IServiceCollection services)
    {
        // the others
      
        services.AddTransient<ICountryService, CountryService>();
    
    }

    4、自定义自己的Taghelper方法

     // 自定义Taghelper类,主要的是要继承TagHelper,位于命名空间Microsoft.AspNetCore.Razor.TagHelpers下
     public class CountryListTagHelper : TagHelper
        {
            private readonly ICountryService _countryService;
    
            public string SelectedValue { get; set; } // 自定义的属性,在后续中会用到
            public CountryListTagHelper(ICountryService countryService)
            {
                _countryService = countryService;
            }
    
            public override void Process(TagHelperContext context, TagHelperOutput output)
            {
                output.TagName = "select";
                output.Content.Clear();
    
                foreach (var item in _countryService.GetAll())
                {
                    var seleted = "";
                    if (SelectedValue != null && SelectedValue.Equals(item.Code, StringComparison.CurrentCultureIgnoreCase))
                    {
                        seleted = " selected="selected"";
                    }
    
                    var listItem = $"<option value="{item.Code}"{seleted}>{item.CnName}-{item.enName}</option>";
                    output.Content.AppendHtml(listItem);
    
                }
    
                //base.Process(context, output);
            }
        }

    因为需要继承TagHelper,所以需要引入以下依赖包(如果用VS2015工具开发,会提示会让你安装什么什么依赖的):

      "Microsoft.AspNetCore.Razor.Runtime": "1.0.0",
       "Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.0"

    其实,这里只是使用到了同步方法,还有一个异步方法,具体定义和描述如下:
    namespace Microsoft.AspNetCore.Razor.TagHelpers
    {
      /// <summary>Class used to filter matching HTML elements.</summary>
      public abstract class TagHelper : ITagHelper
      {
        protected TagHelper();
        /// <inheritdoc />
        public virtual void Init(TagHelperContext context);
        /// <summary>
        /// Synchronously executes the <see cref="T:Microsoft.AspNetCore.Razor.TagHelpers.TagHelper" /> with the given <paramref name="context" /> and
        /// <paramref name="output" />.
        /// </summary>
        /// <param name="context">Contains information associated with the current HTML tag.</param>
        /// <param name="output">A stateful HTML element used to generate an HTML tag.</param>
        public virtual void Process(TagHelperContext context, TagHelperOutput output);
        /// <summary>
        /// Asynchronously executes the <see cref="T:Microsoft.AspNetCore.Razor.TagHelpers.TagHelper" /> with the given <paramref name="context" /> and
        /// <paramref name="output" />.
        /// </summary>
        /// <param name="context">Contains information associated with the current HTML tag.</param>
        /// <param name="output">A stateful HTML element used to generate an HTML tag.</param>
        /// <returns>A <see cref="T:System.Threading.Tasks.Task" /> that on completion updates the <paramref name="output" />.</returns>
        /// <remarks>By default this calls into <see cref="M:Microsoft.AspNetCore.Razor.TagHelpers.TagHelper.Process(Microsoft.AspNetCore.Razor.TagHelpers.TagHelperContext,Microsoft.AspNetCore.Razor.TagHelpers.TagHelperOutput)" />.</remarks>
        /// .
        public virtual Task ProcessAsync(TagHelperContext context, TagHelperOutput output);
        /// <inheritdoc />
        /// <remarks>Default order is <c>0</c>.</remarks>
        public virtual int Order { get; }
      }
    }

      轮子到此就算是造好了,那就需要要检测一下是否能跑吧。

    5、应用检测

    我这里就把这个引用放到了单个view页面中了,(以下三种方式,任选其一即可)

    // 格式:@addTagHelper typeName,AssemblyName
    // 方式一,程序集下所有的Taghelper
    @addTagHelper *,TodoList.Project
    // 方式二,明确指定路径 @addTagHelper "TodoList.Project.Extensions.CountryListTagHelper,TodoList.Project" // 方式三,模糊匹配 @addTagHelper "TodoList.Project.Extensions.CountryList*,TodoList.Project"

    标签引入方式为:

    <country-list selected-value="China"></country-list>
    

    效果图如下:

    生成的html代码为:

    <select><option value="China" selected="selected">中国-China</option><option value="Japan">日本-Japan</option><option value="America">美国-America</option></select>

    其实这里涉及到了两个地方,一个是创建项目时,自带的_ViewImports.cshtml,这个文件是干嘛的呢?个人理解是view中需要导入的一些命名空间之类的。而且是全局使用的。

    如果你要是单独一个view使用,那么就在对应的view页面中增加即可。

    对于标签的命名规则:

      大概是:如果有多个大写字母组成的(比如CountryList),那么会把大写全部转换为小写,然后分割单词(比如:CountryList--->country-list);

      如果是单个单词,则直接转小写;(比如EmailTagHelper ---> email);

    如果,你想自己指定html标签属性,可以在TagHelper上增加一个属性标签:

        [HtmlTargetElement("country-lists")]
        public class CountryListTagHelper : TagHelper

    使用的时候,就是<country-lists selected-value="China"></country-lists>

    6、后记

    主要是有一些疑问,我大概翻了一下源码,也没找到对于自定义的Taghelper,在前面页面中使用的命名规则是什么样子的。就断断续续看到过一些备注上的示例。这让我有点不爽。(谁找到了,麻烦告诉一下在哪里)

    其实,也有一些自带的Taghelper,都在命名空间Microsoft.AspNetCore.Mvc.TagHelpers下,比如:FormTagHelper、InputTagHelper、selectTagHelper、LabelTagHelper、validationTagHelper等;

    比如selectTagHelper,可以这么玩:

    SelectListItem[] items =
      {
         new SelectListItem() {Text = "男♂", Value = "1"},
         new SelectListItem() {Text = "女♀", Value = "0"}
      };
    
    ViewBag.gender
    = items;
     <select asp-for="Sex" id="inputSex" asp-items="@ViewBag.gender">
         <option selected="selected" value="">Choose gender</option>
     </select>

    扩展:

    对于系统自带的一些TagHelper的使用小知识点记录 

    • AnchorTagHelper
    /// <summary>
      /// <see cref="T:Microsoft.AspNetCore.Razor.TagHelpers.ITagHelper" /> implementation targeting &lt;a&gt; elements.
      /// </summary>
      [HtmlTargetElement("a", Attributes = "asp-action")]
      [HtmlTargetElement("a", Attributes = "asp-controller")]
      [HtmlTargetElement("a", Attributes = "asp-area")]
      [HtmlTargetElement("a", Attributes = "asp-fragment")]
      [HtmlTargetElement("a", Attributes = "asp-host")] // 
      [HtmlTargetElement("a", Attributes = "asp-protocol")] // The protocol for the URL, such as "http" or "https".
    [HtmlTargetElement("a", Attributes = "asp-route")] 
    [HtmlTargetElement(
    "a", Attributes = "asp-all-route-data")]
    [HtmlTargetElement(
    "a", Attributes = "asp-route-*")]
    public class AnchorTagHelper : TagHelper

    使用方法:跳转到指定ID的详情页面,并且是https方式

    <a asp-action="Edit" asp-protocol="https" asp-controller="Todo" asp-route-id="@item.Id">@item.Title</a>

    需要注意的是asp-route-*, 可以匹配路由规则中的其他参数

     /// <summary>Additional parameters for the route.</summary>
        [HtmlAttributeName("asp-all-route-data", DictionaryAttributePrefix = "asp-route-")]
        public IDictionary<string, string> RouteValues { get; set; }

    参考资料:

     https://docs.asp.net/en/latest/mvc/views/tag-helpers/intro.html

    http://www.cnblogs.com/TomXu/p/4496480.html
    
    点滴积累,每天进步一点点!O(∩_∩)O~
  • 相关阅读:
    S MVC 转发与重定向
    S MVC Controller方法返回值
    S MVC 表单提交
    numpy数据平滑
    Python入门
    Django
    python机器学习基础教程-监督学习
    drf-CBV
    numpy数组符号化与函数向量化
    numpy中多项式拟合与复数
  • 原文地址:https://www.cnblogs.com/hager/p/5817335.html
Copyright © 2011-2022 走看看