Модель иерархического представления MVC3 с флажками и переключателями - PullRequest
1 голос
/ 09 февраля 2012

Я собираюсь вырвать те мелкие волосы, которые у меня остались - я изучал MVC в течение последних нескольких месяцев, так что я относительно новичок в этом, хотя я прошел большую часть работы ...

У меня возникают проблемы при попытке вывести флажки и переключатели с относительно сложной моделью представления.

У меня есть следующее представление (ненужные поля удалены):

@model CreateMediumModel
@using(Html.BeginForm()) {
                <div class="formField">
                    <div class="label">
                        @Html.LabelFor(m => m.MetaData)
                    </div>
                    <div class="input">
                        @Html.EditorFor(m => m.MetaData)
                    </div>
                    @Html.ValidationMessageFor(m => m.MetaData)
                </div>

}

Модель иерархического представления выглядит следующим образом:

public class CreateMediumModel {
    public List<MetaData> MetaData { get; set; }
}

public class MetaData {
    /// <summary>
    /// The media type that this meta data belongs to.
    /// </summary>
    public int MediaTypeID { get; set; }

    /// <summary>
    /// The unique ID for the meta data.
    /// </summary>
    public int MetaDataID { get; set; }

    /// <summary>
    /// The unique text-based identifier for the meta data. Unique per MediaType.
    /// </summary>
    public string Key { get; set; }

    /// <summary>
    /// The UI description of the meta data.
    /// </summary>
    public string Description { get; set; }

    /// <summary>
    /// The max length of text based data.
    /// </summary>
    public int Length { get; set; }

    /// <summary>
    /// Provides a pre-defined list of values for the meta data.
    /// </summary>
    public List<MetaDataOption> Options { get; set; }

    /// <summary>
    /// Provides the text-based value for the meta data.
    /// </summary>
    public string Value { get; set; }

    /// <summary>
    /// Determines which value/s to use from the object graph
    /// </summary>
    public MetaDataDataType Type { get; set; }

    /// <summary>
    /// Defines the UI sort order of the meta data
    /// </summary>
    public int SortOrder { get; set; }
}

public class MetaDataDataType {
    public int MetaDataTypeID { get; set; }
    public MetaDataDataTypeEnum Type { get; set; }
    public bool TextBased { get; set; }
}

public class MetaDataOption {
    /// <summary>
    /// The unique ID for the option
    /// </summary>
    public int MetaDataOptionID { get; set; }

    /// <summary>
    /// The pre-defined option value to display.
    /// </summary>
    public string Value { get; set; }

    /// <summary>
    /// The sort order of the value in the list.
    /// </summary>
    public int SortOrder { get; set; }
}

public enum MetaDataEnum {
    Developer,
    PEGI,
    PEGIContent
}

public enum MetaDataDataTypeEnum {
    /// <summary>
    /// Simple text
    /// </summary>
    TEXT = 1,

    /// <summary>
    /// Multi-line text.
    /// </summary>
    MULTITEXT = 2,

    /// <summary>
    /// Simple number
    /// </summary>
    NUMBER = 3,

    /// <summary>
    /// Simple date
    /// </summary>
    DATE = 4,

    /// <summary>
    /// Simple time
    /// </summary>
    TIME = 5,

    /// <summary>
    /// Simple DateTime
    /// </summary>
    DATETIME = 6,

    /// <summary>
    /// Single option selection
    /// </summary>
    SELECTION = 7,

    /// <summary>
    /// Multi option selection
    /// </summary>
    MULTISELECTION = 8
}

Каждый фрагмент метаданных имеет один тип;тип определяет, как метаданные редактируются и как они отображаются (и где данные хранятся в слое данных).На стороне дисплея все работает отлично.

Когда тип «ВЫБОР», я хочу отобразить один набор переключателей, где можно выбрать только одну.Когда тип "MULTISELECTION", я хочу отобразить набор флажков, где можно выбрать более одного.Я могу это сделать, но мне удалось успешно привязать выбранные значения к модели.

В данный момент я использую шаблон редактора для отображения списка, который выглядит следующим образом:

@model MetaData
@using Business.Enumerations

@if(Model != null) {
    @Html.HiddenFor(m => m.MetaDataID)
    <div class="metaData@(Model.MediaTypeID) checkbox">
        <div class="metaDescription">
            @Model.Description
        </div>
        <div class="metaValue">
            @switch(Model.Type.Type) {
                case MetaDataDataTypeEnum.NUMBER:
                case MetaDataDataTypeEnum.DATE:
                case MetaDataDataTypeEnum.TEXT:
                case MetaDataDataTypeEnum.TIME:
                case MetaDataDataTypeEnum.DATETIME:
                    @Html.TextBoxFor(m => m.Value)
                    break;
                case MetaDataDataTypeEnum.MULTITEXT:
                    @Html.TextAreaFor(m => m.Value)
                    break;
                case MetaDataDataTypeEnum.SELECTION:
                    foreach(var o in Model.Options) {
                        @Html.RadioButtonFor(m => m.Value, o.MetaDataOptionID) @o.Value
                    }
                    break;
                case MetaDataDataTypeEnum.MULTISELECTION:
                    foreach(var o in Model.Options) {
                        @Html.CheckBoxFor(m => m.Options.FirstOrDefault(opt => opt.Selected).Selected) @o.Value
                    }
                    break;
   }
        </div>
    </div>
}

Это будет расширено, когда я преодолею эту проблему, но сейчас она выводит все как положено - я вижу список переключателей для типов SELECTION и список флажков для типов MULTISELECTION, но он не привязан кмодель правильно, когда я вызываю действие отправки.

Я немного схожу с ума.Может ли кто-нибудь увидеть что-то очевидное, что я делаю неправильно?

В качестве отступления:

Я также пытался создать шаблон редактора для класса MetaDataOption, но, похоже, существует ошибка, связанная спередача списка в шаблон подредактора, когда указано имя шаблона (Html.EditorFor (m => m.Options, "MetaDataOptionsSingle") и Html.EditorFor (m => m.Options, "MetaDataOptionsMulti")) -если я не указываю имя для шаблона редактора, шаблон может иметь модель MetaDataOption, но если указать имя, ему требуется список.

ОБНОВЛЕНИЕ

Хорошо, мне удалось заставить это работать, но сейчас у меня проблемы с ненавязчивой проверкой флажков.Исправление заключается в следующем:

Шаблон редактора MetaData теперь выглядит следующим образом:

@model MetaData
@using Business.Enumerations

@if(Model != null) {
    @Html.HiddenFor(m => m.Description)
    @Html.HiddenFor(m => m.Type)
    <div class="metaData@(Model.MediaTypeID) checkbox">
        <div class="metaDescription">
            @Model.Description
        </div>
        <div class="metaValue">
            @switch (Model.Type) {
                case MetaDataDataTypeEnum.NUMBER:
                case MetaDataDataTypeEnum.DATE:
                case MetaDataDataTypeEnum.TEXT:
                case MetaDataDataTypeEnum.TIME:
                case MetaDataDataTypeEnum.DATETIME:
                    @Html.TextBoxFor(m => m.Value)
                    break;
                case MetaDataDataTypeEnum.MULTITEXT:
                    @Html.TextAreaFor(m => m.Value)
                    break;
                case MetaDataDataTypeEnum.SELECTION:
                    if(Model.Options != null) {
                        foreach (var o in Model.Options) {
                            @Html.RadioButtonFor(m => Model.SelectedMetaDataOptionID, o.MetaDataOptionID)
                            @o.Value
                        }
                    }
                    break;
                case MetaDataDataTypeEnum.MULTISELECTION:
                    @Html.EditorFor(m => m.Options)
                    break;
            }
        </div>
    </div>
}

Я добавил еще один шаблон Editor для шаблона MULTISELECTION Editor:

@model MetaDataOption

@if(Model != null) {
    @Html.HiddenFor(m => m.MetaDataOptionID)
    @Html.CheckBoxFor(m => m.Selected)
    @Model.Value
}

ИКласс MetaDataOption выглядит следующим образом:

public class MetaDataOption {
    /// <summary>
    /// The unique ID for the option
    /// </summary>
    public int MetaDataOptionID { get; set; }

    /// <summary>
    /// The pre-defined option value to display.
    /// </summary>
    public string Value { get; set; }

    /// <summary>
    /// The sort order of the value in the list.
    /// </summary>
    public int SortOrder { get; set; }
}

Модель теперь заполняется правильно при отправке.Однако проверка выполняется во ВСЕХ флажках, отображаемых шаблоном редактора (в методе post-action, поскольку я еще не реализовал проверку клиента), однако аннотации данных для члена «Выбранный» класса MetaDataOption отсутствуют.

На что обратить внимание - член «Опции» класса MetaData имеет значение NULL, если не выбраны никакие флажки.

Я попытался установить для свойства Selected значение nollable bool (bool?), Но я запускаюиз-за проблем с помощником CheckBoxFor () в шаблоне редактора MetaDataOption, который не принимает обнуляемый bool.

Это сводит меня с ума ... Я потратил два дня, пытаясь заставить что-то работатьпросвистил с ASP.Net!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...