内嵌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。 

关于TagHelper的那些事情——自定义TagHelper(内嵌TagHelper)的更多相关文章

  1. 关于TagHelper的那些事情——自定义TagHelper(格式化输出、依赖注入使用)

    自定义TagHelper的最后一步就是在Process方法或ProcessAsync方法中添加展现代码.熟悉WebControl开发的朋友都知道Render方法,在这个方法中会添加展现的Html元素和 ...

  2. 关于TagHelper的那些事情——自定义TagHelper(TagHelper的Attributes)

    接上 Attributes 在最新的VS2015RC版,开始支持了TagHelper的智能提示,主要体现在在写TagHelper有Attributes的提示,正确的Tag和Attribute会变成粗体 ...

  3. 关于TagHelper的那些事情——如何自定义TagHelper(TagHelper基类)

    写在开头 前面介绍了TagHelper的基本概念和内嵌的TagHelpers,想必大家对TagHelper都有一定的了解.TagHelper看上去有点像WebControl,但它不同于WebContr ...

  4. 关于TagHelper的那些事情——Microsoft.AspNet.Mvc.TagHelpers介绍

    写在开始 在上一篇文章中,简单介绍了什么是TagHelper,怎么使用它.接下来我会简单介绍一下微软随着ASP.NET5一起发布的TagHelpers.它们分别是: AnchorTagHelper C ...

  5. 关于TagHelper的那些事情——TagHelper的基本知识

    概要 TagHelper是ASP.NET 5的一个新特性.也许在你还没有听说过它的时候, 它已经在技术人员之间引起了大量讨论,甚至有一部分称它为服务器控件的回归.实际上它只不过是一个简化版本,把HTM ...

  6. react页面内嵌微信二维码 和 自定义样式 以及 微信网页共用unionId问题

    在react页面内嵌“微信二维码”,实现PC端通过微信扫码进行登录.首先去微信开放平台注册一个账号,创建一个网站应用,提交网站备案审核,获取appid和appsecret:其他开发流程根据微信文档来进 ...

  7. 微信小程序页面调用自定义组件内的事件

    微信小程序页面调用自定义组件内的事件 page page.json { "usingComponents": { "my-component": ". ...

  8. 补习系列(17)-springboot mongodb 内嵌数据库

    目录 简介 一.使用 flapdoodle.embed.mongo A. 引入依赖 B. 准备测试类 C. 完善配置 D. 启动测试 细节 二.使用Fongo A. 引入框架 B. 准备测试类 C.业 ...

  9. Word中高效输入公式:内嵌公式和Mathtype

    Word中高效输入公式:内嵌公式和Mathtype 前言:对于理工科学生而言,公式输入必不可缺.LaTeX相比Word,在公式输入及排版方面更强大.但是对于轻量级的任务,用Word而言更加轻便(起码不 ...

随机推荐

  1. sql server 存储过程解密

    Create PROCEDURE [dbo].[sp_windbi$decrypt] () AS /**//* 王成辉翻译整理,转贴请注明出自微软BI开拓者www.windbi.com 调用形式为: ...

  2. Python全栈开发之6、正则表达式

    转载请注明出处http://www.cnblogs.com/Wxtrkbc/p/5498162.html 正则表达式使用单个字符串来描述.匹配一系列符合某个句法规则的字符串,在文本处理方面功能非常强大 ...

  3. Codeforces Round #278 (Div. 1) D - Conveyor Belts 分块+dp

    D - Conveyor Belts 思路:分块dp, 对于修改将对应的块再dp一次. #include<bits/stdc++.h> #define LL long long #defi ...

  4. Java Stream简介, 流的基本概念

    在Javaor .net编程中,  我们经常见到"stream" 这个字眼. 我们大概知道这是个流的意思, 如果看完本文的话, 应该会有1个大概的概念. 一, Java中什么是St ...

  5. 面试的65个回答技巧-适用于BAT公司

    互联网职业群分享的资料,里面大多是BAT公司的人,很多是猎头.这些技巧对于职场人来说,是非常宝贵的. 1.请你自我介绍一下你自己? 回答提示:一般人回答这个问题过于平常,只说姓名.年龄.爱好.工作经验 ...

  6. powershell 性能测试小脚本

    powershell 性能测试: 转载请注明: 仰望高端玩家的小清新 http://www.cnblogs.com/luruiyuan/ 1. 将待测试的脚本封装在代码块中 2. 使用  Get-Ch ...

  7. Void运算符 与 undefined类型

    void 运算符 对给定的表达式进行求值,然后返回 undefined. 何为求值,就是执行之后的表达式. 我们最常见的就是 <a href="javascript: void(0)& ...

  8. 理解裸机部署过程ironic

    部署物理机跟部署虚拟机的概念在nova来看是一样,都是nova通过创建虚拟机的方式来触发,只是底层nova-scheduler和nova-compute的驱动不一样.虚拟机的底层驱动采用的libvir ...

  9. Sea Battle<海战>(思路题)

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  10. FastReport.Net使用:[4]分组

    1.绘制报表标题和栏首. 2.设置报表栏,为数据区添加一个分组 3.右键分组页眉,在其右键菜单中选择“编辑”,显示分组编辑对话框. 设置分组条件,可直接通过下拉菜单选择Table表中的[学号]列:也能 ...