2

次のコードを考えると、次のパターンにならなければならないのはコードの匂いですか?

モデル:

class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public Category Cat { get; set; }
}

class Category
{
    public int Id { get; set; }
    public string Label { get; set; }
}

Product を編集するためのビュー:

<% =Html.EditorFor( x => x.Name ) %>
<% =Html.EditorFor( x => x.Category ) %>

カテゴリの EditorTemplate

<% =Html.DropDownList<Category>() %>

HtmlHelper メソッド

public static MvcHtmlString DropDownList<TEntity>(this HtmlHelper helper)
    where TEntity : Entity
{
    var selectList = new SelectList(
        ServiceLocator.GetInstance<SomethingGivingMe<TEntity>>().GetAll(), 
        "Id", "Label");

    return SelectExtensions.DropDownList(helper, "List", selectList, null, null);
}

参考までに、ヘルパー メソッドの実際の実装では、DataTextField と DataValueField の名前、選択された値などを取得するためにいくつかのラムダが必要です。

気になる点は、HtmlHelper 内で servicelocator を使用していることです。Product モデルに AllCategories プロパティが必要だと思いますが、必要になるたびにコントローラーに値を設定する必要があります。

したがって、ヘルパー メソッドは汎用的であるため、私が使用しているソリューションはより簡単だと思います (ここには含まれていないモデル バインダーも同様です)。したがって、DropDownList を必要とするタイプごとに EditorTemplate を作成するだけです。

何かアドバイス ?

4

2 に答える 2

0

私見私はそれをそのままにして、別のプロジェクトで同じことをします。

しかし、サービスの場所も気になったので、別のプロジェクトでは、モデルをスキャンし、予想されるすべてのドロップダウンを見つけて、ViewData にバッチロードする ActionFilter のこの部分を作成しました。ServiceLocator または Repository/Context/whatever は既に Controller に注入されているため、サービスの場所をあちこちに広げる必要はありません。

public override void OnActionExecuted(ActionExecutedContext filterContext)
{
    foreach( var anticipated in SomeDetectionMethod() )
    {
          var selectList = new SelectList(
    ServiceLocator.GetInstance<SomethingGivingMe<TEntity>>().GetAll(), 
    "Id", "Label");

         ViewData["SelectList." + anticipated.Label/Name/Description"] = selectList;
    }
}

ビューでは、ヘルパーを作成して、カスタム エディター テンプレートまたはその他の方法でこれらのドロップダウンをロードできます。

于 2010-08-05T20:13:12.853 に答える
-1

アドバイス:ここからasp.net mvcサンプルアプリケーションを見てください:http://valueinjecter.codeplex.com/頑張ってください ;)

これは、ValueInjecterのサンプルアプリケーションがドロップダウンを取得する方法です:(しかし、今は解決できません)

public class CountryToLookup : LoopValueInjection<Country, object>
{
    ICountryRepo _repo;

    public CountryToLookup(ICountryRepository repo)
    {
        _repo = repo;
    }

    protected override object SetValue(Country sourcePropertyValue)
    {
        var value = sourcePropertyValue ?? new Country();
        var countries = _repo.GetAll().ToArray();
        return
            countries.Select(
                o => new SelectListItem
                         {
                             Text = o.Name,
                             Value = o.Id.ToString(),
                             Selected = value.Id == o.Id
                         });
    }
}
于 2010-08-05T20:05:50.110 に答える