Как уменьшить дублирование кода в ASP.NET MVC view при работе с перечислением Flags
Прости мое невежество. Не проделал много работы с 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?
2 ответа
Создать хелпер для бритвы:
@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
когда вы отправляете форму, так как она будет получена только в виде массива значений. Как всегда, используйте модель представления для представления того, что вы хотите отобразить / отредактировать в представлении.
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