WEB程序员笔记

一个前端开发工程师的个人博客

在Blazor App中基于布尔开关值动态构建CSS类字符串

在Angular应用中构建CSS类字符串。

在编写Angular SPA程序时,可以编写这样的代码来控制CSS类字符串。

// my.component.ts
@Component({template:'my.component.html',...})
export class MyComponent {
  rotate: boolean;
  disabled: boolean;
  ...
<!-- my.component.html -->
<div [ngClass]="{'rotate':rotate, 'disabled':disabled}">...

上面的代码将像这样渲染DOM,具体取决于条件rotatedisabled组件的属性是否正确。

<div class="rotate disabled">...

ngClass我认为,这个Angular 指令是直观而直接的。

开拓者的方式有点痛苦…

顺便说一句,当我编写Blazor C#SPA程序时,控制CSS类字符串有点痛苦。

我不得不编写一个代码来判断条件并自己连接CSS类字符串,而不是像Angular那样。

@* MyComponent.razor *@
<div class="@CssClass()">...

@code {
  bool Rotate;
  bool Disabled;

  // Should I implement a code like this everytime 
  // when I need to build CSS class string? Help me!
  string CssClass() {
    var cssClass = new List<string>();
    if (this.Rotate) cssClass.Add("rotate");
    if (this.Disabled) cssClass.Add("disabled");
    return string.Join(' ', cssClass);
  }
  ...

我对上述解决方案不满意。

我能做什么?

基本概念

因此,我决定创建一个实用程序函数来从匿名类型对象构建CSS类字符串,就像Angular的方法一样。

效用函数的基本概念是:

  1. 该函数可以传递一个匿名对象。
  2. 该函数bool通过.NET CLR“ Reflection”功能获取参数中对象的属性。
  3. 该函数过滤那些值为的属性true
  4. 最后,该函数返回一个字符串,该字符串将这些属性名称与空格分隔。

我在班级库中实现了这个概念。

我将类命名为CssClassInlineBuilder,并将函数命名CssClass()为静态方法。

CssClass()静态方法的源代码如下:

// CssClassInlineBuilder.cs
public static class CssClassInlineBuilder 
{
  public static string CssClass(object obj)
  {
    var boolPropNames = obj.GetType()
      // Enumarate all properties of the argument object.
      .GetProperties()
      // Filter the properties only it's type is "bool".
      .Where(p => p.PropertyType == typeof(bool))
      // Filter the properties only that value is "true".
      .Where(p => (bool)p.GetMethod().Invoke(obj, null))
      // Collect names of properties, and convert it to lower case.
      .Selec(p => p.Name.ToLower());

    // Concatenate names of filtered properties with space separator.
    return string.Join(' ', boolPropNames);
  }
}

这个类库允许我编写代码,以动态方式构建CSS类字符串,而无需像Angular一样编写代码片段。

@* MyComponent.razor *@
<div class="@CssClassInlineBuilder.CssClass(new {Rotate, Disabled})">...

@code {
  bool Rotate;
  bool Disabled;
  ...

那很棒 ;)

…但是,我仍然对这段代码不满意。

难道你不觉得CssClassInlineBuilder.CssClass(new {...})非常非常过长?

更简化!

一种C#语法帮助了我!

我使用using static指令来省略类名。

@* _Imports.razor *@
...
@using static CssClassInlineBuilder

最后,我只能使用方法名称来编写它!

@* MyComponent.razor *@
<div class="@CssClass(new {Rotate, Disabled})">...

@code {
  bool Rotate;
  bool Disabled;
  ...

是的 :)
(源代码在GitHub上,受“ sushi-go-round”启发。)

《在Blazor App中基于布尔开关值动态构建CSS类字符串》

结论

我仔细研究了此实现,并将该类库作为NuGet包公开。

如果您对该库感兴趣,请访问nuget.org。

《在Blazor App中基于布尔开关值动态构建CSS类字符串》

您可以在GitHub上找到我的工作的更多细节。


使用Blazor进行快乐的编码:)

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注