重复代码
在我的应用程序中,我有这样的代码,这些代码在很多地方重复:
@if (economy.Cash == economy_base.Cash)
{
<span>
"Cash" @(String.Format("{0:N2}", economy.Cash))
</span>
}
else
{
<span>
Cash @(String.Format("{0:N2}", economy_base.Cash))
<span style="color: purple;">
(@(String.Format("{0:N2}", economy.Cash)))
</span>
</span>
}
其中economy.Cash
、economy_base.Cash
和"Cash"
是在每种情况下不同的值。
将其分解为函数
起初,我考虑使用这里描述的适用于ASP的技术。NET核心应用程序:
https://stackoverflow.com/a/67656536/268581
然而,那里的确切方法似乎在Blazor不起作用。
因此,我没有使用async Task Template(...)
的函数签名,而是使用了void Template(...)
。这似乎奏效了!
鉴于此:
@{
void Template(string label, decimal? a, decimal? b)
{
@if (a == b)
{
<span>
@label @(String.Format("{0:N2}", a))
</span>
}
else
{
<span>
@label @(String.Format("{0:N2}", b))
<span style="color: purple;">
(@(String.Format("{0:N2}", a)))
</span>
</span>
}
}
}
我可以使用以下内容:
@{
Template("Cash", economy.Cash, economy_base.Cash);
}
它将扩展到上面第一节中显示的示例代码中。
问题
在定义Template
时,我只是胡乱猜测并尝试了void Template(...)
签名。
我的问题是,这是将Blazor标记因素化为函数的有效且推荐的方法吗?
我的问题是,这是将Blazor标记因子分解到函数中的有效且推荐的方法吗?
它本身没有什么问题,但要注意这不是一个正常的模板。
这里有一个override BuildRenderTree()
内部的本地函数,它是从标记部分生成的。因此,需要使用@ { }
来包围呼叫。
你的其他选择是
-
是一个
RenderFragment<T> Template
,但这需要以某种方式将string label, decimal? a, decimal? b
绑定到一个类型中
使用@Template(new MyType("Cash", economy.Cash, economy_base.Cash))
,无需额外的@{}
-
一个普通的Blazor组件(单独的.rarzor文件(
用法看起来像<Template Label="Cash" A="economy.Cash" B="economy_base.Cash" />
答案已删除-不值得接受。。。
我的问题是,这是一种将Blazor标记因子分解到函数中的有效且推荐的方法吗?
这可能是一种有效的方法,但这不是Blazor中的做法。推荐的方法或者更确切地说是一种好的做法是使用RenderFragment委托类型,它是用来呈现部分标记的。。。
有很多方法可以实现您的功能。。。这里有一个:
复制并测试。。。
@page "/"
@Template(("my label", valA, valB))
@code
{
decimal? valA = 2.34M;
decimal? valB = 3.34M;
private RenderFragment<(string label, decimal? a, decimal? b)> Template => value => __builder =>
{
@if (@value.a == @value.b)
{
<span>
@value.label @(String.Format("{0:N2}", @value.a))
</span>
}
else
{
<span>
@value.label @(String.Format("{0:N2}", @value.b))
<span style="color: purple;">
(@(String.Format("{0:N2}", @value.a)))
</span>
</span>
}
};
}
注意:最好使用RenderFragment代理来代替Rqazor组件。因此,通过组件实现代码的解决方案是一件非常糟糕的事情。组件非常昂贵,不能仅用于呈现内容。
另一种方法,通常比其他方法更可取,是使用模板剃刀代理
@page "/"
@Template(values)
@code
{
private RenderFragment<MyClass> Template = (values) =>@<p>
@if (@values.valA == @values.valB)
{
<span>
@values.Label @(String.Format("{0:N2}", @values.valA))
</span>
}
else
{
<span>
@values.Label @(String.Format("{0:N2}", @values.valB))
<span style="color: purple;">
(@(String.Format("{0:N2}", @values.valA)))
</span>
</span>
}
</p>;
private MyClass values = new MyClass { Label = "my label", valA = 2.34M, valB = 3.34M };
private class MyClass
{
public string Label { get; set; }
public decimal? valA { get; set; }
public decimal? valB { get; set; }
}
}