我刚刚注意到,如果我有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 。我也可以用我喜欢的任何方式更新默认标签助手生成的锚点。对这种行为有任何程度的控制吗?
您可能想要决定是否执行针对同一元素的其他帮助程序(就像密封您的输出一样)。您可能还希望允许其他帮助程序,但请确保未修改某些属性。
答案 0 :(得分:9)
阅读TagHelperRunner
类的源代码,我意识到将为同一元素找到的所有标记助手共享相同的TagHelperContext
和TagHelperOutput
,这些将被处理由ITagHelper.Order
属性订购。
因此,您可以通过为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;
}
如果您扩展班级TagHelper
,默认顺序为0。
像AnchorTagHelper
或InputTagHelper
这样的MVC代码帮助程序似乎将订单定义为-1000。
到目前为止,我还发现您可以查询TagHelperOutput
中的某些属性来检查以前的标记帮助程序是否已修改输出。虽然您无法知道具有更高顺序的标签助手(在您之后执行)是否会修改输出:
TagHelperOutput.IsContentModified
仅在修改内容时才会返回true(不属于属性或PreElement
,PreContent
,PostElement
,PostContent
被修改)
TagHelperOutput.PreElement.IsModified
以及PreContent
,PostElement
和PostContent
的类似内容将在修改后返回true。
可以通过调用TagHelperOutput.Content.Clear()
以及类似的Pre / Post Element / Context属性来删除上一个标记助手设置的内容。
通过调用TagHelperOutput.SuppressOutput()
可以完全抑制内容,TagHelperContext.Items
在每个属性上调用clear,并将TagName设置为null。如果您希望标记帮助器呈现某些内容,则需要再次分配它们。
最后,如果您必须在同一元素的多个标记帮助程序之间共享一些数据,则可以使用public void RaiseEvent<T>(EventHandler<T> eventToRaise, T args) where T : EventArgs, IXmlConvertable
{
Log(eventToRaise.Method.Name, args.ToXElement());
ThreadPool.QueueUserWorkItem((e) => eventToRaise(this, args));
}
public event EventHandler<ProductLeftEventArgs> ProductLeftEvent = delegate { };
字典。