经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » ASP.net » 查看文章
【ASP.NET Core】标记帮助器——替换元素名称
来源:cnblogs  作者:东邪独孤  时间:2023/2/27 9:44:59  对本文有异议

标记帮助器不仅可以给目标元素(标记)插入(或修改)属性,插入自定义的HTML内容,在某些需求中还可以替换原来标记的名称。

比如我们在使用 Blazor 时很熟悉的 Component 标记帮助器。在 Razor 文档中你将使用 <Component> 元素来设置要呈现的组件。而在实际处理时,会去掉 <Component> 元素,并呈现组件的HTML内容。

下面咱们举两个例子。

第一个比较简单,自定义的元素是 <textBox>,生成的元素是 <input type=text />。

  1. [HtmlTargetElement("textBox", TagStructure = TagStructure.WithoutEndTag)]
  2. public class TextInputTagHelper : TagHelper
  3. {
  4. public override void Process(TagHelperContext context, TagHelperOutput output)
  5. {
  6. // 将标记名称改为 input
  7. output.TagName = "input";
  8. // 设置 type 属性
  9. output.Attributes.SetAttribute("type", "text");
  10. }
  11. }

这个不难理解,首先我们用的是候,在 Razor 文档使用的是元素是 <textbox>,而最后呈现出来的 HTML 是 <input> 元素。咱们就把它弄得像个控件那样用,是不是有点以前 ASP.NET 的味儿了?以前是有个前缀 asp:TextBox。

TagStructure.WithoutEndTag 的意思是指定这个标记没有结束标签,就像 <input > 或 <input />。

Razor 文档中要用 @addTagHelper 指令导入一下。

  1. @addTagHelper *, TestApp

TestApp 是我这个程序集的名称,它导入此程序集下所有标记帮助器。

用起来也方便。

  1. <div>
  2. <TextBox />
  3. </div>

运行之后,生成这样的 HTML。

  1. <input type="text">

咱们确实可以让它更像传统 ASP.NET。

  1. @addTagHelper *, TestApp
  2. @tagHelperPrefix "asp:"
  3. <div>
  4. <asp:textBox />
  5. </div>

@tagHelperPrefix 就是为标记添加一个前缀,这里指定的是“asp:”,所以用的时候就真的捡到“童年回忆”了。想当年,ASP.NET 就是这么用的。

 

下面再举一例,咱们做 RadioButton(单选按钮)。选项之间互斥,同一个分组中你只能选择一项。在 HTML 中是 <input type=radio >,它没有“分组”属性,而是通过 name 属性来分组。name 相同的就是同一组,互斥。

注意的是,<input type=radio> 只显示个圈圈让你可以选中,可不包含选项文本。一般我们会给它配个 <label> 元素。然后,<label> 元素的 for 属性指向 <input> 的 id 属性。这样二者就关联了,点击<label>也能选中单选按钮。

所以,咱们实现的帮助器要生成一个<div>,里面包含<input>和<label>两个元素。

  1. [HtmlTargetElement("radioButton", TagStructure = TagStructure.WithoutEndTag)]
  2. public class RadioInputTagHelper : TagHelper {
  3. // 分组名称
  4. [HtmlAttributeName("group-name")]
  5. public string? Group { get; set; } = "radio";
  6. // id 值
  7. public string? Id { get; set; } = string.Empty;
  8. // 标签文本
  9. public string? Label { get; set; }
  10. // 默认是否选中
  11. public bool IsChecked { get; set; } = false;
  12. // 选项代表的值
  13. public string? Value { get; set; } = string.Empty;
  14. public override void Process(TagHelperContext context, TagHelperOutput output)
  15. {
  16. // 修改标记名称
  17. output.TagName = null;
  18. StringBuilder builder = new();
  19. string html = $"""
  20. <div>
  21. <input type="radio" id="{Id}" name="{Group}" value="{Value}" {(IsChecked ? "checked" : "")} />
  22. <label for="{Id}">{Label}</label>
  23. </div>
  24. """;
  25.  
  26. // 设置HTML内容
  27. output.Content.SetHtmlContent(html);
  28. }
  29. }

默认情况下,在 Razor 文档中使用标记帮助器时,属性与.NET类属性相同。比如这个类中的 Label 属性,在Razor代码中也是Label属性。

  1. <radioButton Label="老司机" ……>

如果你希望 HTML 属性与 .NET 属性不同,可以加上 [HtmlAttributeName] 特性,配分一个别名。

  1. [HtmlAttributeName("group-name")]

咱们这个例子中,就为 Group 属性分配一个别名—— group-name。

<label> 元素只是呈现在HTML中的文本,让用户看,很多时候程序处理的往往不是这个,而是让标签对应一个值,即 Value 属性。Value 属性指定的值才是给程序用的。

我们来用一下这个单选按钮。

  1. <div>
  2. <radioButton group-name="abc" id="itme1" value="1" label="山药" is-checked="true" />
  3. <radioButton group-name="abc" id="item2" value="2" label="鸭梨" />
  4. <radioButton group-name="abc" id="item3" value="3" label="龙眼" />
  5. <hr />
  6. <radioButton group-name="good" id="item5" value="5" label="大卡车" />
  7. <radioButton group-name="good" id="item6" value="6" label="皮卡" is-checked="true" />
  8. <radioButton group-name="good" id="item4" value="4" label="独轮车" />
  9. </div>

同一 group-name 下的选项是互斥关系,而不同组之间是互不影响的。

运行后,生成以下 HTML:

  1. <div>
  2. <input type="radio" id="itme1" name="abc" value="1" checked />
  3. <label for="itme1">山药</label>
  4. </div>
  5. <div>
  6. <input type="radio" id="item2" name="abc" value="2" />
  7. <label for="item2">鸭梨</label>
  8. </div>
  9. <div>
  10. <input type="radio" id="item3" name="abc" value="3" />
  11. <label for="item3">龙眼</label>
  12. </div>
  13. <hr />
  14. <div>
  15. <input type="radio" id="item5" name="good" value="5" />
  16. <label for="item5">大卡车</label>
  17. </div>
  18. <div>
  19. <input type="radio" id="item6" name="good" value="6" checked />
  20. <label for="item6">皮卡</label>
  21. </div>
  22. <div>
  23. <input type="radio" id="item4" name="good" value="4" />
  24. <label for="item4">独轮车</label>
  25. </div>
  26. </div>

结果如下图所示。

 

接下来看第三个例子。咱们来画一个圆,标记帮助器定义一个 <circle> 元素,我们直接设置相关属性就行。比如画布宽度、画布高度、圆的圆心、半径、线的粗细。然后会生成 <canvas> 元素和相关的 js 脚本代码。

  1. [HtmlTargetElement("Circle")]
  2. public class CircleTagHelper : TagHelper
  3. {
  4. // 圆的半径
  5. public int Radius { get; set; }
  6. // 线宽度
  7. public int LineWidth { get; set; }
  8. // 圆心-X
  9. public int CenterX { get; set; }
  10. // 圆心-Y
  11. public int CenterY { get; set; }
  12. // 画布宽度
  13. public int Width { get; set; } = 300;
  14. // 画布高度
  15. public int Height { get; set; } = 300;
  16. public override void Process(TagHelperContext context, TagHelperOutput output)
  17. {
  18. // 无标记名称
  19. output.TagName = null;
  20. // 生成的内容
  21. string s = $"""
  22. <canvas id="cv" width="{Width}" height="{Height}"></canvas>
  23. <script>
  24. var canvas = document.getElementById('cv');
  25. var ctx = canvas.getContext('2d');
  26. ctx.lineWidth = {LineWidth};
  27. ctx.strokeStyle = 'blue';
  28. ctx.beginPath();
  29. ctx.arc({CenterX}, {CenterY}, {Radius}, 0, 2 * Math.PI);
  30. ctx.stroke();
  31. </script>
  32. """;
  33. output.Content.SetHtmlContent(s);
  34. }
  35. }

TagName 设置为 null 表示咱们这个帮助器不生产标签,而是用输出字符串 s 中那段代码。即这段代码直接呈现在 HTML 文档中,外部不用其他元素包装。

来,咱们在 Razor 文档中试试看。

  1. <Circle center-x="115" center-y="90"
  2. width="900"
  3. height="900"
  4. line-width="4"
  5. radius="70" />

绘制的圆如下图所示。

 

生成的 HTML 如下:

  1. <canvas id="cv" width="900" height="900"></canvas>
  2.  
  3. <script>
  4. var canvas = document.getElementById('cv');
  5. var ctx = canvas.getContext('2d');
  6. ctx.lineWidth = 4;
  7. ctx.strokeStyle = 'blue';
  8. ctx.beginPath();
  9. ctx.arc(115, 90, 70, 0, 2 * Math.PI);
  10. ctx.stroke();
  11. </script>

用这个方法,咱们可以封装出许多图形绘制的标记,用的时候只要赋值一下属性即可,很省事的哟。

 

原文链接:https://www.cnblogs.com/tcjiaan/p/17157309.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号