2017-05-26 68 views
0

asp-items剃须刀“TagHelper”将为SelectList中的每个值添加<option><select>。我想修改每个孩子。TagHelper;如何修改动态添加的孩子

具体而言,我想禁用其中的一些(即添加disabled="disabled")。

更具体地说,我想动态禁用它们中的一些;我正在使用角度,所以我可以ng-disabled="{dynamic_boolean_which_determines_disabled}"。这意味着该选项可以在第一时间被禁用,但在用户进行更改后,可以禁用该选项(无需重新加载页面)。 Angular应该照顾这个;我觉得角和TagHelpers在理论上应共同努力...

我预计:

我能以某种方式访问​​一个IEnumerable的孩子将被创建<option>标签(即每个项目提供的SelectList ),迭代子标签,和setAttribute( “禁用”)或的setAttribute( “NG-禁用”)...

我想:

  1. 创建我自己的TagHelper,它以select[asp-items]为目标,并尝试使GetChildContentAsync()和/或SetContent达到IEnumerable <option>标记并迭代它们并处理它们,但我认为这只会让我修改整个InnerHtml作为字符串;感觉哈克做一个String.replace,但我可以做到这一点,如果这是我唯一的选择?即ChildrenContent.Replace("<option", "<option disabled=\"...\"")
  2. 创建我自己的TagHelper其目标为option元素是select[asp-items]的孩子,所以我可以每个单独过程。这是有效的,但不是由asp-items创建的动态添加<option>,它只适用于我实际放入我的cshtml标记中的“literal”<option>标记。

我认为这会工作,但并不理想:

  1. 正如我前面所说,我想我可以得到的TagHelper的动态ASP-项目<option></option> <option></option>的结果,作为一个字符串,并做一个字符串替换,但我不喜欢直接使用字符串...
  2. 我怀疑(我还没有尝试过),我可以自己做asp-items的工作;即custom-items。但是,我通过重新执行asp-items可能为我完成的工作来重新创建轮子?
+0

只是要提[@Daniel J.G.(https://stackoverflow.com/users/1836935/daniel-j-g),因为他们似乎知道了很多。但我想“@”该用户[可能不会按我期望的方式工作:]](https://meta.stackexchange.com/questions/43019/how-do-comment-replies-work) –

回答

0

所以我还没有看过“AutoLinkHttpTagHelper” in the example它使用字符串替换(特别是正则表达式替换)替换URL的每一次出现,有<a>指着那个网址。案件稍有不同*,但...

总之,这里是我的解决方案,一旦我学会停止担忧和爱的字符串修改:

[HtmlTargetElement("select", Attributes = "asp-items")] 
public class AspItemsNgDisabledTagHelper : SelectTagHelper 
{ 
    //Need it to process *after* the SelectTagHelper 
    public override int Order { get; } = int.MaxValue; 

    //https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/authoring#ProcessAsync 
    public AspItemsNgDisabledTagHelper(IHtmlGenerator gen) : base(gen) {} 

    public override void Process(TagHelperContext context, TagHelperOutput output) 
    { 
     //Notice I'm getting the PostContent; 
     //SelectTagHelper leaves its literal content (i.e. in your CSHTML, if there is any) alone ; that's Content 
     //it only **appends** new options specified; that's PostContent 
     //Makes sense, but I still wasn't expecting it 
     var generated_options = output.PostContent.GetContent(); 

     //Note you do NOT need to extend SelectTagHelper as I've done here 
     //I only did it to take advantage of the asp-for property, to get its Name, so I could pass that to the angular function 
     var select_for = this.For.Name; 

     //The heart of the processing is a Regex.Replace, just like 
     //their example https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/authoring#inspecting-and-retrieving-child-content 
     var ng_disabled_generated_options = Regex.Replace(
      generated_options, 
      "<option value=\"(\\w+)\">", 
      $"<option value=\"$1\" ng-disabled=\"is_disabled('{select_for}', '$1')\">"); 

     //Finally, you Set your modified Content 
     output.PostContent.SetHtmlContent(ng_disabled_generated_options); 

    } 

}

很少有学习的机会:

  1. 我在想我会找到AspForTagHelperAspItemsTagHelper(角度背景提示相应的属性; asp-forasp-items,将分开“指令“又名TagHelper)。
    1. 事实上,TagHelper“匹配”的重点元素名称(不同于角度可以匹配元素名称... ...属性类... CSS选择器)
    2. 所以我找到了我一直在寻找SelectTagHelper,其中ForItems属性。说得通。
  2. 正如我前面所说,我延长SelectTagHelper,但是这不是必要回答我原来的问题。如果你想像我一样进入this.For.Name,只需要这样做,但是甚至可能会有一种解决方法(即重新绑定它自己的属性)
    1. 我开始分心思考我会需要重写SelectTagHelper的行为来实现我的目标;即面向对象思维。事实上,即使我的确扩展了SelectTagHelper,也不会停止单独的SelectTagHelper实例的匹配和处理元素。换句话说,元素处理发生在流水线中。
    2. 这解释了为什么扩展和调用base.Process(),将导致Select执行其作业两次;一次当你的实例匹配时,再次匹配基础实例。
    3. (我想可以从像<asp-items-select>创建一个新的元素名称匹配已经阻止SelectTagHelper?可是,没必要......我只是避免调用base.Process()。所以,除非这是一个不好的做法...)

*以这种方式不同:

  1. 他们希望创建并不存在一个标记,而我要添加属性的标签这已经有;即<option>
    1. 虽然<option>“标签”是产生由SelectTagHelper在其PostContent(原以为会发现它在Content),我不认为标签生成功能于字符串逐content-mods可以与他们相应的TagHelper匹配 - 所以也许我们真的是一样的,我们只是处理普通的旧字符串
  2. 他们的“数据”又名“模型”隐含在文本本身;他们发现一个URL并且该URL字符串成为他们使用的意义单位。在我的情况下,有一个明确的类建模; SelectList<select>)它由一些SelectListItem<option>)组成 - 但这个班也帮不了我。
    1. 那类只给我属性,如public bool Disabled(请记住,这是不够的,因为我的残疾的数值可能会更改为true或浏览器中的错误,即只有客户端),以及public SelectListGroup Group - 当然没什么作为非标准的ng-disabled,也没有像属性这样的“全部”属性,它可以让我把任意属性(ng-disabled或其他)放在那里。
相关问题