zoukankan      html  css  js  c++  java
  • 关于TagHelper的那些事情——自定义TagHelper(内嵌TagHelper)

    内嵌TagHelper

    上一篇文章中提到有时候需要设计一种内嵌的TagHelper,如下:

    <my name="yy" age="35">
       <location country="China" city="Shanghai" district="PuDong"></location>
    </my>
    

    location就是一个内嵌的TagHelper,我们可以在location里设置与它相关的Attributes,有时候设置有多层内嵌的TagHelper。那么怎样设计出这样的一个内嵌的TagHelper来呢?其实它和一般的TagHelper没什么的区别,大家可以利用前面我们介绍的来设计出它的TagHelper类及Attributes。和一般的TagHelper的主要区别是,它和父TagHelper关联。如何建立这种关联?这也是这章我们需要搞清楚的。

    通过前面章节学习,我们知道设计的自定义TagHelper类都会继承于抽象类TagHelper,在这个类中有二个方法:

    //同步处理
    public virtual void Process(TagHelperContext context, TagHelperOutput output);
    
    //异步处理
    public virtual Task ProcessAsync(TagHelperContext context, TagHelperOutput output);
    

    一般我们会根据实际情况来选择重载哪个方法。在TagHelper抽象类中,异步处理是调用同步处理方法。在这两个方法中参数相同,在这里详细介绍第一个参数context。

    它的类型是TagHelperContext,主要是存放TagHelper相关的信息:

    1. AllAttributes

      TagHelper支持的所有Attribute集合,它是只读的。

    2. Items

      类型是IDictionary<object, object>,它是用来和其他TagHelper进行联系枢纽,

              /// <summary>
              /// Gets the collection of items used to communicate with other <see cref="ITagHelper"/>s.
              /// </summary>
              /// <remarks>
              /// This <see cref="IDictionary{object, object}"/> is copy-on-write in order to ensure items added to this 
              /// collection are visible only to other <see cref="ITagHelper"/>s targeting child elements.
              /// </remarks>
              public IDictionary<object, object> Items { get; }
      

      从上面的描述可以看出,这个集合是copy-on-write,也就是说当前TagHelper在Items获取父TagHelper中的Items信息,也可以修改,删除或者添加某一项,但是不会影响到父TagHelper的Items值,同时也会将修改后的Items信息传给其子TagHelper,子TagHelper的任何修改不会影响到它。

    在上面我们提到,设计支持内嵌TagHelper类,关键是要建立父子TagHelper的联系,看到这里,我想大家都应该清楚如何建立这种关联。对了,就是利用context中Items。

    主要是在TagHelper的Process方法中做以下事情。  

    public virtual void Process(TagHelperContext context, TagHelperOutput output)
    {
       // 从context.items获取父TagHelper信息
       // 处理自身Attributes
       // 将自身信息存放在context.items中
       // 处理自己的子TagHelper
    }
    

    更具体的例子如下:

        //定义父TagHelper
        public class PersonTagHelper : TagHelper
        {
            public string Name
            {
                get { return Person.Name; }
                set { Person.Name = value; }
            }
            public int Age
            {
                get { return Person.Age; }
                set { Person.Age = value; }
            }
    
            private Person _person;
            private Person Person
            {
                get
                {
                    return _person ?? (_person = new Person());
                }
                set
                {
                    _person = value;
                }
            }
            public override void Process(TagHelperContext context, TagHelperOutput output)
            {
                // 保存信息给子TagHelper使用
                context.Items["Parent"] = Person;
                // 执行并获取子TagHelper内容
                context.GetChildContentAsync();
    
                // 输出html元素和启动脚本
                // 这里会用到第二个参数output,后面会介绍到如何使用。
            }
        }
    
        // 定义子TagHelper
        public class LocationTagHelper: TagHelper
        {
            public string Country { get; set; }
            public string City { get; set; }
            public string District { get; set; }
    
            public override void Process(TagHelperContext context, TagHelperOutput output)
            {
                // 获取来自父TagHelper的信息,并保存到变量里去
                var parent = context.Items["Parent"] as Person;
                // 处理Attributes的设置
                parent.Location.Country = Country;
                parent.Location.City = City;
                parent.Location.District = District;
                // 保存自身信息,便于子TagHelper使用
                context.Items["Parent"] = parent.Location;
                // 执行并获取子TagHelper内容
                context.GetChildContentAsync();
            }
        }
    
        // 定义了父TagHelper中对应的对象实例
       // 大家可以根据各自需求,决定是否需要定义这样一个类型
        public class Person
        {
            public string Name { get; set; }
            public int Age { get; set; }
    
            private Location _location;
            public Location Location
            {
                get { return _location ?? (_location = new Location()); }
            }
        }
     
        // 定义子TagHelper中数据类型
        // 大家可以根据各自需求,决定是否需要定义这样一个类型
        public class Location
        {
            public string Country { get; set; }
            public string City { get; set; }
            public string District { get; set; }
        }
    

    对于类Person和Location的定义大家可以根据具体情况来决定是否需要。

    这个例子只是简单展示如何利用Items信息来构建父子TagHelper间的联系,大家在具体的项目开发中根据实际需求,写出不一样的代码来,但有一点不变,就是要利用Items。 

  • 相关阅读:
    【Programming Clip】位运算的应用
    【Linux实用技术】LFS6.3构建实录
    【嵌入式开发技术之环境配置】Ubuntu下 TFTP服务的配置
    IIS上注册.Net
    C#高效分页代码(不用存储过程)
    OpenDataSOurce 指定参数
    存储过程中while循环
    SQL语句中的判断(条件语句)
    C#.NET支付宝接口
    局域网共享访问要密码 局域网访问需要密码 访问网上邻居需要密码 局域网不能共享 windows xp共享
  • 原文地址:https://www.cnblogs.com/liontone/p/4653019.html
Copyright © 2011-2022 走看看