针对同一元素的多个标签助手
Multiple tag helpers targetting the same element
我刚刚注意到,如果我有 2 个标记助手针对同一个元素,则都可以执行。它们执行的顺序取决于它们在_ViewImports.cshtml.
中注册的顺序
例如,我可以为锚元素创建另一个标签助手:
[HtmlTargetElement("a", Attributes = "foo")]
public class FooTagHelper : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
//Get the url from href attribute generated in the default AnchorTagHelper
var url = output.Attributes["href"].Value.ToString();
...
}
}
按如下方式使用它(注意我还添加了默认锚助手的属性,如 asp-controller
):
<a class="menu" asp-controller="Home" asp-action="Index" foo>Foo</a>
如果此助手在 _ViewImports.cshtml 之后 默认 ASP 注册:
- 每当调用
Process
时,TagHelperOutput
已经包含默认 AnchorTagHelper
生成的 href。我还可以以任何我喜欢的方式更新由默认标签助手生成的锚点。
对这种行为有任何程度的控制吗?
您可能想决定是否针对同一元素执行进一步的帮助程序(就好像 密封 您的输出)。您可能还想允许其他助手,但请确保未修改某些属性。
覆盖只读的属性命令,像这样:
[HtmlTargetElement("a", Attributes = "foo")]
public class FooTagHelper : TagHelper
{
// This should be the last tag helper on any tag to run
public override int Order => int.MaxValue;
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
//...
}
}
阅读 TagHelperRunner
class 的源代码,我意识到相同的 TagHelperContext
和 TagHelperOutput
将被所有找到的标签助手共享元素,将按 ITagHelper.Order
属性.
顺序处理
因此您可以通过为订单分配适当的值来控制它们的执行顺序 属性。作为参考,这是 TagHaelperRunner.RunAsync
方法:
public async Task<TagHelperOutput> RunAsync([NotNull] TagHelperExecutionContext executionContext)
{
var tagHelperContext = new TagHelperContext(
executionContext.AllAttributes,
executionContext.Items,
executionContext.UniqueId,
executionContext.GetChildContentAsync);
var tagHelperOutput = new TagHelperOutput(
executionContext.TagName,
executionContext.HTMLAttributes)
{
SelfClosing = executionContext.SelfClosing,
};
var orderedTagHelpers = executionContext.TagHelpers.OrderBy(tagHelper => tagHelper.Order);
foreach (var tagHelper in orderedTagHelpers)
{
await tagHelper.ProcessAsync(tagHelperContext, tagHelperOutput);
}
return tagHelperOutput;
}
如果扩展 class TagHelper
,则默认订单为 0。
像 AnchorTagHelper
or InputTagHelper
这样的 MVC 标签助手似乎将顺序定义为 -1000。
到目前为止,我还发现您可以查询 TagHelperOutput
中的一些属性来检查以前的标签助手是否修改了输出。尽管您不知道是否有更高阶的标签助手(在您之后执行)修改了输出:
TagHelperOutput.IsContentModified
仅当内容被修改时才会 return 为真(当属性或 PreElement
、PreContent
、PostElement
, PostContent
被修改)
TagHelperOutput.PreElement.IsModified
以及 PreContent
、PostElement
和 PostContent
的类似内容将 return 在修改后为真。
可以通过调用 TagHelperOutput.Content.Clear()
和类似的 Pre/Post Element/Context 属性来删除之前标记助手设置的内容。
可以通过调用 TagHelperOutput.SuppressOutput()
来完全抑制内容,它会在每个属性上调用 clear 并将 TagName 设置为 null。如果您希望标签助手呈现某些内容,则需要再次分配它们。
最后,如果您必须在同一个元素的多个标签助手之间共享一些数据,您可以使用 TagHelperContext.Items
字典。
我刚刚注意到,如果我有 2 个标记助手针对同一个元素,则都可以执行。它们执行的顺序取决于它们在_ViewImports.cshtml.
中注册的顺序例如,我可以为锚元素创建另一个标签助手:
[HtmlTargetElement("a", Attributes = "foo")]
public class FooTagHelper : TagHelper
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
//Get the url from href attribute generated in the default AnchorTagHelper
var url = output.Attributes["href"].Value.ToString();
...
}
}
按如下方式使用它(注意我还添加了默认锚助手的属性,如 asp-controller
):
<a class="menu" asp-controller="Home" asp-action="Index" foo>Foo</a>
如果此助手在 _ViewImports.cshtml 之后 默认 ASP 注册:
- 每当调用
Process
时,TagHelperOutput
已经包含默认AnchorTagHelper
生成的 href。我还可以以任何我喜欢的方式更新由默认标签助手生成的锚点。
对这种行为有任何程度的控制吗?
您可能想决定是否针对同一元素执行进一步的帮助程序(就好像 密封 您的输出)。您可能还想允许其他助手,但请确保未修改某些属性。
覆盖只读的属性命令,像这样:
[HtmlTargetElement("a", Attributes = "foo")]
public class FooTagHelper : TagHelper
{
// This should be the last tag helper on any tag to run
public override int Order => int.MaxValue;
public override async Task ProcessAsync(TagHelperContext context,
TagHelperOutput output)
{
//...
}
}
阅读 TagHelperRunner
class 的源代码,我意识到相同的 TagHelperContext
和 TagHelperOutput
将被所有找到的标签助手共享元素,将按 ITagHelper.Order
属性.
因此您可以通过为订单分配适当的值来控制它们的执行顺序 属性。作为参考,这是 TagHaelperRunner.RunAsync
方法:
public async Task<TagHelperOutput> RunAsync([NotNull] TagHelperExecutionContext executionContext)
{
var tagHelperContext = new TagHelperContext(
executionContext.AllAttributes,
executionContext.Items,
executionContext.UniqueId,
executionContext.GetChildContentAsync);
var tagHelperOutput = new TagHelperOutput(
executionContext.TagName,
executionContext.HTMLAttributes)
{
SelfClosing = executionContext.SelfClosing,
};
var orderedTagHelpers = executionContext.TagHelpers.OrderBy(tagHelper => tagHelper.Order);
foreach (var tagHelper in orderedTagHelpers)
{
await tagHelper.ProcessAsync(tagHelperContext, tagHelperOutput);
}
return tagHelperOutput;
}
如果扩展 class
TagHelper
,则默认订单为 0。像
AnchorTagHelper
orInputTagHelper
这样的 MVC 标签助手似乎将顺序定义为 -1000。
到目前为止,我还发现您可以查询 TagHelperOutput
中的一些属性来检查以前的标签助手是否修改了输出。尽管您不知道是否有更高阶的标签助手(在您之后执行)修改了输出:
TagHelperOutput.IsContentModified
仅当内容被修改时才会 return 为真(当属性或PreElement
、PreContent
、PostElement
,PostContent
被修改)TagHelperOutput.PreElement.IsModified
以及PreContent
、PostElement
和PostContent
的类似内容将 return 在修改后为真。可以通过调用
TagHelperOutput.Content.Clear()
和类似的 Pre/Post Element/Context 属性来删除之前标记助手设置的内容。可以通过调用
TagHelperOutput.SuppressOutput()
来完全抑制内容,它会在每个属性上调用 clear 并将 TagName 设置为 null。如果您希望标签助手呈现某些内容,则需要再次分配它们。
最后,如果您必须在同一个元素的多个标签助手之间共享一些数据,您可以使用 TagHelperContext.Items
字典。