0

ドキュメントに関連するさまざまな「属性」フィールドを表すドロップダウンがあります。たとえば、ドキュメントに[タグ]フィールドを含めることができます。このフィールドには、タグを入力するためのテキストボックスが必要です。または、[場所]フィールドがあり、ユーザーが選択できるさまざまな場所の種類のドロップダウンが事前に入力されている場合があります。または、Deadlineフィールドである可能性があり、日付の選択に使用するカスタムの日付ピッカーがあります。

私の問題:適切な属性フィールドを選択したときに起動するHtmlHelperをコントローラーアクション内で宣言したかったのです。Attribute.Typeとは何かを切り替え、タイプに応じて、ビューでレンダリングする適切なhtmlをビューモデルに返します。このようにした場合、switchステートメントを単体テストできます。

コントローラーでHtmlHelperを宣言するのは悪い考えだということをよく読んでいます。私は感情を理解することができます-私がこれを行うことができるより良い方法はありますか?ユニットテストがまったくできないので、可能な限りロジックを避けたいと思います。

これを行うもう1つの方法は、ビューモデルでAttribute.Typeを渡し、ビューでスイッチロジックを実行して、呼び出すHtmlHelperメソッドを決定することです。それは行く方法ですか?前もって感謝します。

編集:私はコードビハインドでこのようなことをしたいということについて話している。私の単体テストは、viewModel.FieldHtmlに対してアサートします。私が聞いているのは、これを別のクラスに入れて、コントローラーに呼び出させる必要があるということです。しかし、これがコントローラーでの外観です。これは単なる擬似コードなので完璧ではありませんが、私が求めているものにコンテキストを与えるためのものです。

public ActionResult GetValueInput(Guid attributeFieldUid)
{
    //you have to pass some stuff into the constructor but essentially this
    HtmlHelper html = new HtmlHelper();
    AttributeField field = GetAttributeFieldFromDb(attributeFieldUid);

    AttributeViewModel viewModel = new AttributeViewModel();
    switch(field.type)
    {
        case Dropdown:
            viewModel.FieldHtml = html.DropDownList();
            break;
        case Text:
            viewModel.FieldHtml = html.TextBox();
            break;
        case Date:
            // our own extension method
            viewModel.FieldHtml = html.OurDatePicker();
            break;
    }
}

私が最初に見た他のオプションは、基本的にかみそりのビューでこのswitchステートメントを実行することでした。しかし、コントローラーが最も呼び出す別のクラスでこれを行うというアイデアが好きだと思います。

これは本当に設計上の質問です。これを実装する方法が最も理にかなっているのでしょうか。

4

2 に答える 2

1

このためのカスタムHTMLヘルパーを作成できます。したがって、コントローラーアクションは、ビューモデルを埋めて、それをビューに渡す責任があります。

public ActionResult GetValueInput(Guid attributeFieldUid)
{
    AttributeField field = GetAttributeFieldFromDb(attributeFieldUid);
    AttributeViewModel viewModel = new AttributeViewModel();
    viewModel.FieldType = field.type;
    return View(viewModel);
}

次に、ヘルパーを作成します。

public static class HtmlExtensions
{
    public static IHtmlString Field(this HtmlHelper html, FieldType type)
    {
        switch(field.type)
        {
            case Dropdown:
                return html.DropDownList(... you will probably need some more info on your view model to be passed here to generate a dropdown)
            case Text:
                return html.TextBox(...);
            case Date:
                return html.OurDatePicker();
        }

        return MvcHtmlString.Empty;
    }
}

このヘルパーは、ビューで使用されます。

@model AttributeViewModel
@Html.Field(Model.FieldType)

もう1つの可能性は、エディターテンプレートを使用することです。これが例です。

于 2012-04-26T06:08:33.187 に答える
0

うーん、AOPの仕事のようですね。

非常に簡単です。カスタム属性を作成して、必要な追加のパラメーターを使用してフィールドのタイプを指定できます。

public class CustomAttribute : Attribute
{
    private readonly FieldType _fieldType;
    public CustomAttribute(FieldType fieldType)
    {
        _fieldType = fieldType;
    }
    public FieldType FieldType { get { return _fieldType; } }
}

そして、ビューモデルのプロパティに注釈を付けます。

[Custom(FieldType.CheckBox)]
public int SomeField { get; set; }

次に、htmlヘルパー拡張メソッドexを記述します。

public static class CustomHtmlHelperExtensions
{
    public MvcHtmlString CustomControlFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel,TProperty>> memberExpression)
    {
        var member = ((MemberExpression)model.Body).Member;
        var customAttribute = member.GetAttributes().OfType<CustomAttribute>().Cast<CustomAttribute>().SingleOrDefault();
        if(customAttribute == null)
        //Perform certain logic if the property doesn't have the attribute specified
        //ex. return null;
        switch(customAttribute.FieldType)
        {
            case FieldType.TextBox: 
                {
                    //Do something
                    return htmlHelper.TextBoxFor(memberExpression);
                }
            default: break;
        }
        return null;
    }
}

それは少なくともあなたが始めるはずです:)

于 2012-04-27T20:18:37.480 に答える