2

私のコントローラーコード

public ActionResult Create(string id)
    {
        ViewBag.ALLO_ID = new SelectList(_unitOfWork.AllocationMRepository.Get(), "ALLO_ID", "ALLO_ID", id);
        ViewBag.TERR_ID = new SelectList(_unitOfWork.TerrListRepository.Get().OrderBy(m => m.TERR_ID), "TERR_ID", "TERR_ID");
        ViewBag.ITEM_ID = new SelectList(_unitOfWork.SampleInfo.Get(), "ITEM_ID", "ITEM_ID");
        return View();
    } 

私からしてみれば

<div class="editor-field">
                @Html.DropDownList("ALLO_ID", String.Empty)
                @Html.ValidationMessageFor(model => model.ALLO_ID)
            </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.TERR_ID, "Territory Name")
        </div>
        <div class="editor-field">
            @Html.DropDownList("TERR_ID", String.Empty)
            @Html.ValidationMessageFor(model => model.TERR_ID)
        </div>

        <div class="editor-label">
            @Html.LabelFor(model => model.ITEM_ID, "Item Name")
        </div>
        <div class="editor-field">
            @Html.DropDownList("ITEM_ID", String.Empty)
            @Html.ValidationMessageFor(model => model.ITEM_ID)
        </div>

これらのドロップ ドロップ リストはどのように作成されますか? 私にはあまり明確ではありません。どのように機能するのか知りたいです。くだらない質問かもしれませんが初心者なので教えていただきたいです。

ありがとうございます。

4

1 に答える 1

2

ソースを入手して、マシン上でビルドします。真剣に。私は自分のコピーを頻繁に参照します。

特定の質問に答えるには、つまり「フレームワークはどのようにドロップダウン リストを作成していますか?」列挙可能なコレクションを反復処理し、文字列を作成しています。

MVC ライブラリは、HtmlHelperクラスの多数の拡張メソッドを定義します。自分で簡単に定義できます。もちろん、他のヘルパー クラスを作成することもできますが、HtmlHelperこの目的のためだけにすぐに利用できます。

オーバーロードのいくつかのレイヤーをステップ実行すると、次のことがわかります。

private IHtmlString BuildDropDownList(string name, string defaultOption, IEnumerable<SelectListItem> selectList, 
            object selectedValue, IDictionary<string, object> htmlAttributes) {

    var modelState = ModelState[name];
    if (modelState != null) {
        selectedValue = selectedValue ?? ModelState[name].Value;
    }
    selectedValue = ConvertTo(selectedValue, typeof(string));

    if (selectedValue != null) {
        var newSelectList = new List<SelectListItem>(from item in selectList select new SelectListItem(item));
        var comparer = StringComparer.InvariantCultureIgnoreCase;
        var selectedItem = newSelectList.FirstOrDefault(item => item.Selected || comparer.Equals(item.Value ?? item.Text, selectedValue));
        if (selectedItem != default(SelectListItem)) {
            selectedItem.Selected = true;
            selectList = newSelectList;
        }
    }

    TagBuilder tagBuilder = new TagBuilder("select") {
        InnerHtml = BuildListOptions(selectList, defaultOption)
    };
    tagBuilder.MergeAttributes(htmlAttributes);
    tagBuilder.MergeAttribute("name", name, replaceExisting: true);
    tagBuilder.GenerateId(name);

    // If there are any errors for a named field, we add the css attribute.
    AddErrorClass(tagBuilder, name);

    return tagBuilder.ToHtmlString(TagRenderMode.Normal);
}

それほど複雑ではありません。「For」サフィックスを使用する拡張メソッドは、もう少し洗練されています。

@Html.LabelFor(model => model.TERR_ID, "Territory Name")

ラムダ式に注目してください。フレームワークは実際には実行しません。代わりに、それをメタデータとして解析し、それを使用してアイテムの完全修飾名を取得します。DataAnnotationsこれを使用して、検証に関連するものなど、元のプロパティからさまざまな情報を取得できます。

実装の核心は、private static MvcHtmlString SelectInternal(...)に含まれていSystem.Web.Mvc.Html.SelectExtensionsます。モデルの状態と検証との統合は注目に値します。

于 2013-06-05T05:08:59.110 に答える