查看: 479|回复: 0

[ASP.NET教程] 详解asp.net core封装layui组件示例分享

发表于 2018-1-3 08:00:01

用什么封装?这里只是用了TagHelper,是啥?自己瞅文档去

在学习使用TagHelper的时候,最希望的就是能有个Demo能够让自己作为参考

  • 怎么去封装一个组件?
  • 不同的情况怎么去实现?
  • 有没有更好更高效的方法?

找啊找啊找,最后跑去看了看mvc中的TagHelpers,再好好瞅了瞅TagHelper的文档

勉强折腾了几个组件出来,本来想一个组件一个组件写文章的,但是发现国庆已经结束了~

Demo下载

效果预览

代码仅供参考,有不同的意见也忘不吝赐教

Checkbox复选框组件封装

标签名称:cl-checkbox

标签属性: asp-for:绑定的字段,必须指定

  1. asp-items:绑定单选项 类型为:IEnumerable
  2. asp-skin:layui的皮肤样式,默认or原始
  3. asp-title:若只是一个复选框时显示的文字,且未指定items,默认Checkbox的值为true

其中在封装的时候看源代码发现两段非常有用的代码

1.判断是否可以多选:

代码如下:
var realModelType = For.ModelExplorer.ModelType; //通过类型判断是否为多选 var _allowMultiple = typeof(string) != realModelType && typeof(IEnumerable).IsAssignableFrom(realModelType);

2.获取模型绑定的列表值(多选的情况)

代码如下:
var currentValues = Generator.GetCurrentValues(ViewContext,For.ModelExplorer,expression: For.Name,allowMultiple: true);

这3句代码是在mvc自带的SelectTagHelper中发现的.

因为core其实已经提供了非常多的TagHelper,比如常用的select就是很好的参考对象,封装遇到问题的时候去找找看指不定就又意外的收获.

CheckboxTagHelper代码

  1. using System.Collections.Generic;
  2. using Microsoft.AspNetCore.Mvc.Rendering;
  3. using Microsoft.AspNetCore.Mvc.ViewFeatures;
  4. using Microsoft.AspNetCore.Razor.TagHelpers;
  5. namespace LayuiTagHelper.TagHelpers
  6. {
  7. /// <summary>
  8. /// 复选框
  9. /// </summary>
  10. /// <remarks>
  11. /// 当Items为空时显示单个,且选择后值为true
  12. /// </remarks>
  13. [HtmlTargetElement(CheckboxTagName)]
  14. public class CheckboxTagHelper : TagHelper
  15. {
  16. private const string CheckboxTagName = "cl-checkbox";
  17. private const string ForAttributeName = "asp-for";
  18. private const string ItemsAttributeName = "asp-items";
  19. private const string SkinAttributeName = "asp-skin";
  20. private const string SignleTitleAttributeName = "asp-title";
  21. protected IHtmlGenerator Generator { get; }
  22. public CheckboxTagHelper(IHtmlGenerator generator)
  23. {
  24. Generator = generator;
  25. }
  26. [ViewContext]
  27. public ViewContext ViewContext { get; set; }
  28. [HtmlAttributeName(ForAttributeName)]
  29. public ModelExpression For { get; set; }
  30. [HtmlAttributeName(ItemsAttributeName)]
  31. public IEnumerable<SelectListItem> Items { get; set; }
  32. [HtmlAttributeName(SkinAttributeName)]
  33. public CheckboxSkin Skin { get; set; } = CheckboxSkin.默认;
  34. [HtmlAttributeName(SignleTitleAttributeName)]
  35. public string SignleTitle { get; set; }
  36. public override void Process(TagHelperContext context, TagHelperOutput output)
  37. {
  38. //获取绑定的生成的Name属性
  39. string inputName = ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(For?.Name);
  40. string skin = string.Empty;
  41. #region 风格
  42. switch (Skin)
  43. {
  44. case CheckboxSkin.默认:
  45. skin = "";
  46. break;
  47. case CheckboxSkin.原始:
  48. skin = "primary";
  49. break;
  50. }
  51. #endregion
  52. #region 单个复选框
  53. if (Items == null)
  54. {
  55. output.TagName = "input";
  56. output.TagMode = TagMode.SelfClosing;
  57. output.Attributes.Add("type", "checkbox");
  58. output.Attributes.Add("id", inputName);
  59. output.Attributes.Add("name", inputName);
  60. output.Attributes.Add("lay-skin", skin);
  61. output.Attributes.Add("title", SignleTitle);
  62. output.Attributes.Add("value", "true");
  63. if (For?.Model?.ToString().ToLower() == "true")
  64. {
  65. output.Attributes.Add("checked", "checked");
  66. }
  67. return;
  68. }
  69. #endregion
  70. #region 复选框组
  71. var currentValues = Generator.GetCurrentValues(ViewContext,For.ModelExplorer,expression: For.Name,allowMultiple: true);
  72. foreach (var item in Items)
  73. {
  74. var checkbox = new TagBuilder("input");
  75. checkbox.TagRenderMode = TagRenderMode.SelfClosing;
  76. checkbox.Attributes["type"] = "checkbox";
  77. checkbox.Attributes["id"] = inputName;
  78. checkbox.Attributes["name"] = inputName;
  79. checkbox.Attributes["lay-skin"] = skin;
  80. checkbox.Attributes["title"] = item.Text;
  81. checkbox.Attributes["value"] = item.Value;
  82. if (item.Disabled)
  83. {
  84. checkbox.Attributes.Add("disabled", "disabled");
  85. }
  86. if (item.Selected || (currentValues != null && currentValues.Contains(item.Value)))
  87. {
  88. checkbox.Attributes.Add("checked", "checked");
  89. }
  90. output.Content.AppendHtml(checkbox);
  91. }
  92. output.TagName = "";
  93. #endregion
  94. }
  95. }
  96. public enum CheckboxSkin
  97. {
  98. 默认,
  99. 原始
  100. }
  101. }
复制代码

使用示例

  1. @{
  2. string sex="男";
  3. var Items=new List<SelectListItem>()
  4. {
  5. new SelectListItem() { Text = "男", Value = "男" },
  6. new SelectListItem() { Text = "女", Value = "女"},
  7. new SelectListItem() { Text = "不详", Value = "不详",Disabled=true }
  8. };
  9. }
  10. <cl-checkbox asp-items="Model.Items" asp-for="Hobby1" asp-skin="默认"></cl-checkbox>
  11. <cl-checkbox asp-for="Hobby3" asp-title="单个复选框"></cl-checkbox>
复制代码

Radio单选框组件封装

标签名称:cl-radio

  1. 标签属性: asp-for:绑定的字段,必须指定
  2. asp-items:绑定单选项 类型为:IEnumerable

太简单了,直接上代码了

RadioTagHelper代码

  1. using System;
  2. using System.Collections.Generic;
  3. using Microsoft.AspNetCore.Mvc.Rendering;
  4. using Microsoft.AspNetCore.Mvc.ViewFeatures;
  5. using Microsoft.AspNetCore.Razor.TagHelpers;
  6. namespace LayuiTagHelper.TagHelpers
  7. {
  8. /// <summary>
  9. /// 单选框
  10. /// </summary>
  11. [HtmlTargetElement(RadioTagName)]
  12. public class RadioTagHelper : TagHelper
  13. {
  14. private const string RadioTagName = "cl-radio";
  15. private const string ForAttributeName = "asp-for";
  16. private const string ItemsAttributeName = "asp-items";
  17. [ViewContext]
  18. public ViewContext ViewContext { get; set; }
  19. [HtmlAttributeName(ForAttributeName)]
  20. public ModelExpression For { get; set; }
  21. [HtmlAttributeName(ItemsAttributeName)]
  22. public IEnumerable<SelectListItem> Items { get; set; }
  23. public override void Process(TagHelperContext context, TagHelperOutput output)
  24. {
  25. if (For == null)
  26. {
  27. throw new ArgumentException("必须绑定模型");
  28. }
  29. foreach (var item in Items)
  30. {
  31. var radio = new TagBuilder("input");
  32. radio.TagRenderMode = TagRenderMode.SelfClosing;
  33. radio.Attributes.Add("id", ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(For.Name));
  34. radio.Attributes.Add("name", ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(For.Name));
  35. radio.Attributes.Add("value", item.Value);
  36. radio.Attributes.Add("title", item.Text);
  37. radio.Attributes.Add("type", "radio");
  38. if (item.Disabled)
  39. {
  40. radio.Attributes.Add("disabled", "disabled");
  41. }
  42. if (item.Selected || item.Value == For.Model?.ToString())
  43. {
  44. radio.Attributes.Add("checked", "checked");
  45. }
  46. output.Content.AppendHtml(radio);
  47. }
  48. output.TagName = "";
  49. }
  50. }
  51. }
复制代码

使用示例

  1. @{
  2. string sex="男";
  3. var Items=new List<SelectListItem>()
  4. {
  5. new SelectListItem() { Text = "男", Value = "男" },
  6. new SelectListItem() { Text = "女", Value = "女"},
  7. new SelectListItem() { Text = "不详", Value = "不详",Disabled=true }
  8. };
  9. }
  10. <cl-radio asp-items="@Items" asp-for="sex"></cl-radio>
复制代码

最后再来一个开关组件

单个复选框其实可以直接用开关代替,恰巧layui中也有,于是也将开关单独的封装了一下,代码大同小异

就这个

使用也简单:

  1. namespace LayuiTagHelper.TagHelpers
  2. {
  3. /// <summary>
  4. /// 开关
  5. /// </summary>
  6. [HtmlTargetElement(SwitchTagName)]
  7. public class SwitchTagHelper : TagHelper
  8. {
  9. private const string SwitchTagName = "cl-switch";
  10. private const string ForAttributeName = "asp-for";
  11. private const string SwitchTextAttributeName = "asp-switch-text";
  12. protected IHtmlGenerator Generator { get; }
  13. public SwitchTagHelper(IHtmlGenerator generator)
  14. {
  15. Generator = generator;
  16. }
  17. [ViewContext]
  18. public ViewContext ViewContext { get; set; }
  19. [HtmlAttributeName(ForAttributeName)]
  20. public ModelExpression For { get; set; }
  21. [HtmlAttributeName(SwitchTextAttributeName)]
  22. public string SwitchText { get; set; } = "ON|OFF";
  23. public override void Process(TagHelperContext context, TagHelperOutput output)
  24. {
  25. string inputName = ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(For?.Name);
  26. output.TagName = "input";
  27. output.TagMode = TagMode.SelfClosing;
  28. if (For?.Model?.ToString().ToLower() == "true")
  29. {
  30. output.Attributes.Add("checked", "checked");
  31. }
  32. output.Attributes.Add("type", "checkbox");
  33. output.Attributes.Add("id", inputName);
  34. output.Attributes.Add("name", inputName);
  35. output.Attributes.Add("value", "true");
  36. output.Attributes.Add("lay-skin", "switch");
  37. output.Attributes.Add("lay-text", SwitchText);
  38. }
  39. }
  40. }
复制代码

总结

封装的还很粗糙,正常的使用是没问题的,若发现问题,还望指出。

因为layui是直接在页面加载后渲染的表单标签,故没有多少和layui相关的样式。

除了一些表单组件之外,其实还对选项卡,时间轴,分页,代码显示组件做了一些封装,这些后面再介绍了。

当然,有兴趣的朋友可以先去一睹为快看看都实现了哪些组件

仓库地址

WeDemo分支clone命令:git clone https://git.coding.net/yimocoding/WeDemo.git -b LayuiTagHelper

选项卡,时间轴,分页,代码显示等Demo打包下载

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持程序员之家。



回复

使用道具 举报