在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,具体取决于条件rotate
和disabled
组件的属性是否正确。
<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的方法一样。
效用函数的基本概念是:
- 该函数可以传递一个匿名对象。
- 该函数
bool
通过.NET CLR“ Reflection”功能获取参数中对象的属性。 - 该函数过滤那些值为的属性
true
。 - 最后,该函数返回一个字符串,该字符串将这些属性名称与空格分隔。
我在班级库中实现了这个概念。
我将类命名为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”启发。)
结论
我仔细研究了此实现,并将该类库作为NuGet包公开。
如果您对该库感兴趣,请访问nuget.org。
您可以在GitHub上找到我的工作的更多细节。
使用Blazor进行快乐的编码:)