.net – 优雅的foreach – 在Razor构建
发布时间:2020-05-24 09:41:34 所属栏目:asp.Net 来源:互联网
导读:很多模板引擎都有一种特殊的语法,它是foreach和else的结合.基本上,当foreach循环没有任何迭代时执行else子句.如果要在列表回退中显示某种没有项目,这可能很有用. 以Twig为例,for loop可以是这样的 {% for user in users %} li{{ user.username|e }}/li{% else
|
很多模板引擎都有一种特殊的语法,它是foreach和else的结合.基本上,当foreach循环没有任何迭代时执行else子句.如果要在列表回退中显示某种没有项目,这可能很有用. 以Twig为例, {% for user in users %}
<li>{{ user.username|e }}</li>
{% else %}
<li><em>no user found</em></li>
{% endfor %}
使用Razor View Engine,模板会像这样,包括对集合中项目数量的额外检查: @foreach (var user in users) {
<li>@user.UserName</li>
}
@if (!users.Any()) {
<li><em>no user found</em></li>
}
所以我的问题是:我们可以使用Razor View Engine以某种方式实现类似的优雅. 解决方法巩固Jamiec和Martin Booth的答案.我创建了以下扩展方法.它将IEnumerable作为第一个参数,然后使用两个委托来呈现文本.在Razor Views中,我们可以向Templated Delegates传递两个这样的参数.简而言之,这意味着您可以提供模板.所以这是扩展方法以及如何调用它:public static HelperResult Each<TItem>(this IEnumerable<TItem> items,Func<TItem,HelperResult> eachTemplate,Func<dynamic,HelperResult> other)
{
return new HelperResult(writer =>
{
foreach (var item in items)
{
var result = eachTemplate(item);
result.WriteTo(writer);
}
if (!items.Any())
{
var otherResult = other(new ExpandoObject());
// var otherResult = other(default(TItem));
otherResult.WriteTo(writer);
}
});
}
并在剃刀视图中: @Model.Users.Each(
@<li>@item.Name</li>,@<li>
<b>No Items</b>
</li>
)
总而言之,非常干净. 更新实施评论中提出的建议.此扩展方法使用一个参数循环集合中的项并返回自定义HelperResult.在那个helperresult上,如果没有找到任何项目,可以调用Else方法传入模板委托. public static class HtmlHelpers
{
public static ElseHelperResult<TItem> Each<TItem>(this IEnumerable<TItem> items,HelperResult> eachTemplate)
{
return ElseHelperResult<TItem>.Create(items,eachTemplate);
}
}
public class ElseHelperResult<T> : HelperResult
{
private class Data
{
public IEnumerable<T> Items { get; set; }
public Func<T,HelperResult> EachTemplate { get; set; }
public Func<dynamic,HelperResult> ElseTemplate { get; set; }
public Data(IEnumerable<T> items,Func<T,HelperResult> eachTemplate)
{
Items = items;
EachTemplate = eachTemplate;
}
public void Render(TextWriter writer)
{
foreach (var item in Items)
{
var result = EachTemplate(item);
result.WriteTo(writer);
}
if (!Items.Any() && ElseTemplate != null)
{
var otherResult = ElseTemplate(new ExpandoObject());
// var otherResult = other(default(TItem));
otherResult.WriteTo(writer);
}
}
}
public ElseHelperResult<T> Else(Func<dynamic,HelperResult> elseTemplate)
{
RenderingData.ElseTemplate = elseTemplate;
return this;
}
public static ElseHelperResult<T> Create(IEnumerable<T> items,HelperResult> eachTemplate)
{
var data = new Data(items,eachTemplate);
return new ElseHelperResult<T>(data);
}
private ElseHelperResult(Data data)
: base(data.Render)
{
RenderingData = data;
}
private Data RenderingData { get; set; }
}
然后可以按如下方式调用它: @(Model.Users
.Each(@<li>@item.Name</li>)
.Else(
@<li>
<b>No Users</b>
</li>
)
) (编辑:安卓应用网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
相关内容
- asp.net-mvc-3 – MVC 3 knockoutjs:在使用EditorFor作为布
- asp.net – 网站和虚拟目录之间有什么区别
- asp.net-mvc – 解耦Microsoft.AspNet.Identity.*
- asp.net-mvc-4 – ValidateInput(false)vs AllowHtml
- .net – 洋葱建筑中的依赖性解析
- asp.net-web-api – Web API中的多态:单端点可能?
- asp.net-core – .NET Core的静态代码分析工具
- 使用ASP.NET MVC进行Windows身份验证
- 我可以使用ASP.NET Core仅针对.NET 4.6.1吗?
- asp.net-mvc-2 – 使用或不使用AutoMapper的“合并”模型和
推荐文章
站长推荐
- asp.net-mvc – HandleErrorAttribute无法正常工
- asp.net+Ajax 文本文件静态分页实现代码
- asp.net-mvc – ASP.NET MVC 3发布日期?
- asp.net-mvc – 如何在MVC中创建通用视图模型?
- asp.net-mvc – ASP.NET MVC模型/ ViewModel验证
- 如何在ASP.NET中的多个子域中共享会话?
- asp.net-mvc – 流畅的验证自定义验证规则
- asp.net-mvc – DotNetOpenAuth在ASP.NET MVC中的
- asp.net – Web Api 2:“样例不可用”
- asp.net – Cookies和子域名
热点阅读
