2017-05-26 37 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或其他)放在那裏。
相關問題