2015-10-03 29 views
4

我刚刚注意到,如果我有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

这实际上应该是[HtmlTargetElement(“a”,Attributes =“foo”)] –

+0

感谢您指出这一点,老问题从beta天! –

回答

7

TagHelperRunner类的源代码,我发现相同TagHelperContextTagHelperOutput将用于发现同一元件中的所有标签助手,这将被处理由ITagHelper.Order属性orderd共享。

因此,您可以通过将指定的值分配给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; 
} 

到目前为止,我还发现,你可以查询一些属性的TagHelperOutput检查,如果前一个标签助手已经修改了输出。虽然你可以不知道,如果具有较高位标记辅助(你后执行)修改输出:只有当内容被修改

  • TagHelperOutput.IsContentModified将返回true(而不是当属性或PreElementPreContentPostElementPostContent被修改)

  • TagHelperOutput.PreElement.IsModified和类似的PreContentPostElementPostContent当那些已被修改将返回true。

  • 可以通过调用TagHelperOutput.Content.Clear()以及类似的Pre/Post Element/Context属性来删除以前的标签助手设置的内容。

  • 通过调用TagHelperOutput.SuppressOutput()可以完全抑制内容,该调用在每个属性上调用clear并将TagName设置为null。如果你想让标签助手渲染某些东西,那么你需要重新分配它们。

最后,如果你要共享多个标签之间的助手一些数据,对于相同的元素,你可以使用TagHelperContext.Items字典。

+0

伟大的研究,谢谢@ daniel-j-g。 – bocanegra