使用 Flags 枚举时如何减少 ASP.NET MVC 视图中的代码重复
How to reduce code duplication in ASP.NET MVC view when working with Flags enum
原谅我的无知。没有完成很多 MVC 工作,我相信一定有更好的方法来做到这一点,但我似乎找不到它。我有一个像这样的 Flags 枚举:
[Flags]
public enum Services
{
Foo = 1,
Bar = 2,
Meh = 4
}
我的模型上的 SelectedServices 属性 具有此类型的值。在视图中,我为每个可能的服务都有一个复选框。我已经实现了这样的绑定逻辑:
<div><label><input type="checkbox" name="services" value="@((int)Services.Foo)"
@if(Model.SelectedServices.HasFlag(Services.Foo))
{
<text>checked</text>
}
/>Foo</label></div>
<div><label><input type="checkbox" name="services" value="@((int)Services.Bar)"
@if(Model.SelectedServices.HasFlag(Services.Bar))
{
<text>checked</text>
}
/>Bar</label></div>
等等。哪个有效,但真的非常混乱。
肯定有更好的方法来封装它 - 但我不知道 MVC 中的相关概念是什么?
创建剃须刀助手:
@helper DisplayFlagHelper(Services flag)
{
<div><label><input type="checkbox" name="services" value="@((int)flag)"
if(Model.SelectedServices.HasFlag(flag))
{
<text>checked</text>
}
/>@flag</label></div>
}
@DisplayFlagHelper(Services.Foo)
或共享视图
当您提交表单时,您当前的代码不会绑定到您的 enum
,因为它只会作为值数组接收。一如既往,使用视图模型来表示您想要在视图中显示的内容。display/edit。
public class MyViewModel
{
[Display(Name = "Foo")]
public bool IsFoo { get; set; }
[Display(Name = "Bar")]
public bool IsBar { get; set; }
[Display(Name = "Meh")]
public bool IsMeh { get; set; }
.... // other properties of your view model
}
并将 enum
值映射到视图模型
model.IsFoo= yourEnumProperty.HasFlag(Type.Foo); // etc
并在视图中
@model MyViewModel
....
@Html.CheckBoxFor(m => m.IsFoo)
@Html.LabelFor(m => m.IsFoo)
@Html.CheckBoxFor(m => m.IsBar)
@Html.LabelFor(m => m.IsBar)
....
最后在 POST 方法中
[HttpPost]
public ActionResult Edit(MyViewModel model)
{
bool isTypeValid = model.IsFoo || model.IsBar || model.IsMeh;
if (!isTypeValid)
{
// add a ModelState error and return the view
}
Services myEnumValue = model.IsFoo ? Services.Foo : 0;
myEnumValue |= model.IsBar ? Services.Bar : 0;
myEnumValue |= model.IsMeh ? Services.Meh : 0;
// map the view model to an instance of the data model, save and redirect
原谅我的无知。没有完成很多 MVC 工作,我相信一定有更好的方法来做到这一点,但我似乎找不到它。我有一个像这样的 Flags 枚举:
[Flags]
public enum Services
{
Foo = 1,
Bar = 2,
Meh = 4
}
我的模型上的 SelectedServices 属性 具有此类型的值。在视图中,我为每个可能的服务都有一个复选框。我已经实现了这样的绑定逻辑:
<div><label><input type="checkbox" name="services" value="@((int)Services.Foo)"
@if(Model.SelectedServices.HasFlag(Services.Foo))
{
<text>checked</text>
}
/>Foo</label></div>
<div><label><input type="checkbox" name="services" value="@((int)Services.Bar)"
@if(Model.SelectedServices.HasFlag(Services.Bar))
{
<text>checked</text>
}
/>Bar</label></div>
等等。哪个有效,但真的非常混乱。
肯定有更好的方法来封装它 - 但我不知道 MVC 中的相关概念是什么?
创建剃须刀助手:
@helper DisplayFlagHelper(Services flag)
{
<div><label><input type="checkbox" name="services" value="@((int)flag)"
if(Model.SelectedServices.HasFlag(flag))
{
<text>checked</text>
}
/>@flag</label></div>
}
@DisplayFlagHelper(Services.Foo)
或共享视图
当您提交表单时,您当前的代码不会绑定到您的 enum
,因为它只会作为值数组接收。一如既往,使用视图模型来表示您想要在视图中显示的内容。display/edit。
public class MyViewModel
{
[Display(Name = "Foo")]
public bool IsFoo { get; set; }
[Display(Name = "Bar")]
public bool IsBar { get; set; }
[Display(Name = "Meh")]
public bool IsMeh { get; set; }
.... // other properties of your view model
}
并将 enum
值映射到视图模型
model.IsFoo= yourEnumProperty.HasFlag(Type.Foo); // etc
并在视图中
@model MyViewModel
....
@Html.CheckBoxFor(m => m.IsFoo)
@Html.LabelFor(m => m.IsFoo)
@Html.CheckBoxFor(m => m.IsBar)
@Html.LabelFor(m => m.IsBar)
....
最后在 POST 方法中
[HttpPost]
public ActionResult Edit(MyViewModel model)
{
bool isTypeValid = model.IsFoo || model.IsBar || model.IsMeh;
if (!isTypeValid)
{
// add a ModelState error and return the view
}
Services myEnumValue = model.IsFoo ? Services.Foo : 0;
myEnumValue |= model.IsBar ? Services.Bar : 0;
myEnumValue |= model.IsMeh ? Services.Meh : 0;
// map the view model to an instance of the data model, save and redirect