Как я могу высушить код в моих шаблонах редактора MVC? - PullRequest
0 голосов
/ 05 июня 2018

Со временем я создал несколько удобных пользовательских attributes для шаблонов моего редактора.

Но доступ к их значениям в каждом шаблоне начал забивать их загрузкой повторяющегося кода.

Я рассматриваю возможность создания модели для требуемых свойств.Затем создайте его экземпляр в шаблоне, например:

var editorTemplatePropertySet = new EditorTemplatePropertySet(ViewData, ModelMetadata)

Мои вопросы:

  • Каковы общие подходы к управлению кодом в шаблонах редактора?
  • Существуют ли какие-либо ресурсы, освещающие эту проблему?Я не смог найти ни одного
  • Это плохо пахнет, что там так много кода?

Пример шаблона редактора:

Это код вверху, который повторяется в большинстве шаблонов.

@model decimal?

@{
    var displayName = ModelMetadata.FromLambdaExpression(x => x, ViewData).DisplayName;
    var displayDescription = ModelMetadata.FromLambdaExpression(x => x, ViewData).Description;

    var placeholderAttribute = ModelMetadata.FromLambdaExpression(x => x, ViewData).GetPropertyAttribute<PlaceholderTextAttribute>();
    string placeholderText = (placeholderAttribute == null ? "" : placeholderAttribute.Text);

    var importantInformationAttribute = ModelMetadata.FromLambdaExpression(x => x, ViewData).GetPropertyAttribute<ImportantInformationAttribute>();
    string importantInformationText = (importantInformationAttribute == null ? "" : importantInformationAttribute.Information);

    var inputGroupAddonAttribute = ModelMetadata.FromLambdaExpression(x => x, ViewData).GetPropertyAttribute<InputGroupAddonAttribute>();
    string inputGroupIconClasses = (inputGroupAddonAttribute == null ? "" : inputGroupAddonAttribute.IconClasses);
    string inputGroupText = (inputGroupAddonAttribute == null ? "" : inputGroupAddonAttribute.Text);
    bool isInputGroup = !(string.IsNullOrWhiteSpace(inputGroupIconClasses) && string.IsNullOrWhiteSpace(inputGroupText));


    var htmlAttributesFromView = ViewData["htmlAttributes"] ?? new { };
    var defaultAttributesForEditorType = ViewBag.ClearTextField == true ? new { @class = "form-control FormEditor__input clear-text-field input-block-level" } : new { @class = "form-control input-block-level" };
    var htmlAttributes = Html.MergeHtmlAttributes(htmlAttributesFromView, defaultAttributesForEditorType);
}



<div class="form-group FormEditor">
    @Html.LabelFor(x => x, new { @class = "control-label FormEditor__label" })

    @if (!String.IsNullOrEmpty(importantInformationText))
    {
        <div class="FormEditor__important-information">@Html.Raw(importantInformationText)</div>
    }


    <div class="@(isInputGroup ? "input-group" : "")">

        @if (!string.IsNullOrEmpty(inputGroupIconClasses))
        {
            <span class="input-group-addon">
                <i class="@inputGroupIconClasses"></i>
            </span>
        }
        else if (!string.IsNullOrEmpty(inputGroupText))
        {
            <span class="input-group-addon">@inputGroupText</span>
        }

        @Html.TextBox(
            "",
            Model == null ? "" : String.Format(System.Globalization.CultureInfo.CurrentCulture, "{0:F2}", ViewData.ModelMetadata.Model),
            htmlAttributes)
    </div>

    @if (!String.IsNullOrEmpty(displayDescription))
    {
        <div class="help-block FormEditor__description">@Html.Raw(displayDescription)</div>
    }
    @Html.ValidationMessageFor(x => x, null, new { @class = "FormEditor__validation-message" })


</div>

Обновление - окончательный код

Это код, который я использовал в конечном итоге - класс набора данных:

public class EditorTemplateDataset
{
    public string DisplayName { get; set; }
    public string DisplayDecription { get; set; }
    public string Placeholder { get; set; }
    public string ImportantInformation { get; set; }
    public InputGroupAddonType InputGroupAddonType { get; set; }
    public string InputGroupAddonValue { get; set; }
}

public enum InputGroupAddonType
{
    None,
    Icon,
    Text
}

С помощью метода расширения:

public static class ModelMetadataExtensionMethods
{
    public static EditorTemplateDataset ToEditorTemplateDataset(this ModelMetadata source)
    {
        var dataset = new EditorTemplateDataset();

        dataset.DisplayName = source.DisplayName;
        dataset.DisplayDecription = source.Description;

        var placeholderAttribute = source.GetPropertyAttribute<PlaceholderTextAttribute>();
        dataset.Placeholder = (placeholderAttribute == null ? string.Empty : placeholderAttribute.Text);

        var importantInformationAttribute = source.GetPropertyAttribute<ImportantInformationAttribute>();
        dataset.ImportantInformation = (importantInformationAttribute == null ? string.Empty : importantInformationAttribute.Information);

        var inputGroupAddonAttribute = source.GetPropertyAttribute<InputGroupAddonAttribute>();
        if (inputGroupAddonAttribute == null)
        {
            dataset.InputGroupAddonType = InputGroupAddonType.None;
            dataset.InputGroupAddonValue = string.Empty;
        }
        else
        {
            dataset.InputGroupAddonType = inputGroupAddonAttribute.Type;
            dataset.InputGroupAddonValue = inputGroupAddonAttribute.Value;
        }

        return dataset;
    }

    public static T GetPropertyAttribute<T>(this ModelMetadata source)
        where T : Attribute
    {
        var result = source.ContainerType
          .GetProperty(source.PropertyName)
          .GetCustomAttributes(typeof(T), false)
          .Select(a => a as T)
          .FirstOrDefault(a => a != null);

        return result;
    }
}

Позвольте мне использовать его в шаблонах редактора следующим образом:

@model decimal?


@{
    var modelMetadata = ModelMetadata.FromLambdaExpression(x => x, ViewData);
    var etDataset = modelMetadata.ToEditorTemplateDataset();

    var htmlAttributesFromView = ViewData["htmlAttributes"] ?? new { };
    var defaultAttributesForEditorType = ViewBag.ClearTextField == true ? new { @class = "form-control FormEditor__input clear-text-field input-block-level" } : new { @class = "form-control input-block-level" };
    var htmlAttributes = FP.WpBasic.Core.StaticHelpers.HtmlAttributeHelper.MergeHtmlAttributes(htmlAttributesFromView, defaultAttributesForEditorType);
}



<div class="form-group FormEditor">
    @Html.LabelFor(x => x, new { @class = "control-label FormEditor__label" })

    @if (!String.IsNullOrEmpty(etDataset.ImportantInformation))
    {
        <div class="FormEditor__important-information">@Html.Raw(etDataset.ImportantInformation)</div>
    }


    <div class="@(etDataset.InputGroupAddonType != InputGroupAddonType.None ? "input-group" : "")">

        @if (etDataset.InputGroupAddonType == InputGroupAddonType.Icon)
        {
            <span class="input-group-addon">
                <i class="@etDataset.InputGroupAddonValue"></i>
            </span>
        }
        else if (etDataset.InputGroupAddonType == InputGroupAddonType.Text)
        {
            <span class="input-group-addon">@etDataset.InputGroupAddonValue</span>
        }

        @Html.TextBox(
            "",
            Model == null ? "" : String.Format(System.Globalization.CultureInfo.CurrentCulture, "{0:F2}", ViewData.ModelMetadata.Model),
            htmlAttributes)
    </div>

    @if (!String.IsNullOrEmpty(etDataset.DisplayDecription))
    {
        <div class="help-block FormEditor__description">@Html.Raw(etDataset.DisplayDecription)</div>
    }
    @Html.ValidationMessageFor(x => x, null, new { @class = "FormEditor__validation-message" })


</div>
...