【问题标题】:Combine TagHelper statements结合 TagHelper 语句
【发布时间】:2017-10-11 06:56:23
【问题描述】:

我使用asp core 2.0 MVC,经常使用这样的代码形式:

<form asp-controller="Foo" asp-action="Bar">                
  <div class="form-group">
     <label asp-for="Age"></label>
     <input asp-for="Age" class="form-control"/>
     <span asp-validation-for="Age" class="text-danger"></span>
  </div>

  <div class="form-group">
     <label asp-for="Name"></label>
     <input asp-for="Name" class="form-control"/>
     <span asp-validation-for="Name" class="text-danger"></span>
  </div>
</form>

有没有办法在 TagHelper 类中结合标签、输入和跨度标签来编写如下内容:

  <div class="form-group">
    <foo for="Age">
  </div>

这将产生以下内容:

 <label asp-for="Age"></label>
 <input asp-for="Age" class="form-control"/>
 <span asp-validation-for="Age" class="text-danger"></span>

避免一遍又一遍地为我的属性编写这 3 个常用标签?

提前谢谢你。

编辑:

嗨,伊斯玛,谢谢你的回答。 您的代码生成简单的

<label asp-for="Age"></label>
<input asp-for="Age" class="form-control"/>
<span asp-validation-for="Age" class="text-danger"></span>

html。

但我想要像

这样的“已处理”版本
<input asp-for="Age"/>

<input type="number" data-val="true" data-val-range="The field Age must be between 0 and 100." data-val-range-max="100" data-val-range-min="0" data-val-required="The Age field is required." id="Age" name="Age" value="" />

在html中

有没有办法做到这一点?

【问题讨论】:

    标签: c# asp.net razorengine


    【解决方案1】:

    这可能对你有用,或者至少让你朝着正确的方向前进,我使用了一个自定义 TagHelper,它使用他们的 TagHelper 实现生成其他元素并附加所有输出(可能有更好/更清洁的方法来做到这一点,顺便说一句)。

    [HtmlTargetElement("myfield")]
    public class MyFieldTagHelper : TagHelper
    {
        private IHtmlGenerator _htmlGenerator;
        public MyFieldTagHelper(IHtmlGenerator htmlGenerator)
        {
            _htmlGenerator = htmlGenerator;
        }
    
        public string LabelContent { get; set; }
        public string ValidationContent { get; set; }
    
        [HtmlAttributeName("asp-for")]
        public ModelExpression For { get; set; }
    
        [HtmlAttributeNotBound]
        [ViewContext]
        public ViewContext ViewContext { get; set; }
    
        public override void Process(TagHelperContext context, TagHelperOutput output)
        {
            var labelContext = CrateTagHelperContext();
            var labelOutput = CrateTagHelperOutput("label");
    
            labelOutput.Content.Append(LabelContent);
    
            if (For != null)
            {
                labelOutput.Attributes.Add("for", For.Name);
            }
    
            var label = new LabelTagHelper(_htmlGenerator)
            {
                ViewContext = ViewContext
            };
    
            label.Process(labelContext, labelOutput);
    
    
            var inputContext = CrateTagHelperContext();
            var inputOutput = CrateTagHelperOutput("input");
    
            inputOutput.Attributes.Add("class", "form-control");
    
            var input = new InputTagHelper(_htmlGenerator)
            {
                For = For,
                ViewContext = ViewContext
            };
    
            input.Process(inputContext, inputOutput);
    
            var validationContext = CrateTagHelperContext();
            var validationOutput = CrateTagHelperOutput("span");
    
            validationOutput.Content.Append(ValidationContent);
    
            validationOutput.Attributes.Add("class", "text-danger");
    
            var validation = new ValidationMessageTagHelper(_htmlGenerator)
            {
                For = For,
                ViewContext = ViewContext
            };
    
            validation.Process(validationContext, validationOutput);
    
            output.TagName = "";
            output.Content.AppendHtml(labelOutput);
            output.Content.AppendHtml(inputOutput);
            output.Content.AppendHtml(validationOutput);
        }
    
        private static TagHelperContext CrateTagHelperContext()
        {
            return new TagHelperContext(
                new TagHelperAttributeList(),
                new Dictionary<object, object>(),
                Guid.NewGuid().ToString("N"));
        }
    
        private static TagHelperOutput CrateTagHelperOutput(string tagName)
        {
            return new TagHelperOutput(
                tagName,
                new TagHelperAttributeList(),
                (a,b) =>
                {
                    var tagHelperContent = new DefaultTagHelperContent();
                    tagHelperContent.SetContent(string.Empty);
                    return Task.FromResult<TagHelperContent>(tagHelperContent);
                });
        }
    }
    

    现在在您看来,您应该能够做到这一点:

     <myfield label-content="This is a label" validation-content="Validation content" asp-for="Age"></myfield> 
    

    它会为你生成整个区块。

    记住在你有标签助手的地方注册程序集,即使你的 Web 应用程序中有它们,你也可以通过编辑文件 Views/_ViewImports.cshtml 并添加以下行来做到这一点:

    @addTagHelper *, YourAssemblyName
    

    更多信息:https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro

    【讨论】:

    • 嗨 Isma,你能检查一下我在 ini 帖子中的“编辑”吗?
    • 嘿,对不起@GrayFox,我完全忽略了你问题的复杂性。我再次尝试更新了我的答案,希望我们现在更接近。让我知道结果是什么。
    • 嘿,再次感谢您。输入工作正常。但是标签和验证是空的。我得到 html,但预期的行为是 。似乎 label.Process(labelContext, labelOutput);出于任何原因都不起作用
    • 对于标签,您必须在标签中设置内容
    • 我更新了答案,“for”和内容应该显示在标签和验证中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-30
    • 2017-07-17
    • 1970-01-01
    • 1970-01-01
    • 2020-01-26
    • 2019-04-08
    相关资源
    最近更新 更多