2

ViewBagsを使用することは一般的に悪い習慣であり、ViewBagとViewModelを混在させることも悪いことだと読みましたが、いくつかのViewBagsを使用しsort orderてコントローラーとビューの間でパラメーターを渡していますが、ビューのプロパティを作成できViewModelますそもそもモデルを作成する前に値が必要なので、これを回避する方法がわかりません。

コントローラ

public ActionResult Index(string sortOrder, string searchString, 
                          string currentFilter, int? page, 
                          bool? includeComplete)
{

 ViewBag.CurrentSort = sortOrder;
 ViewBag.NameSortParam = string.IsNullOrWhiteSpace(sortOrder) ? "Name desc" : "";
 ViewBag.DateSortParam = sortOrder == "Date" ? "Date desc" : "Date";

 if (Request.HttpMethod == "GET")
     searchString = currentFilter;
 else
     page = 1;

 ViewBag.CurrentFilter = searchString;
 bool showCompleted = (includeComplete == null || includeComplete == false)
                        ? false : true;
 ViewBag.IncludeCompleted = showCompleted;

 int pageNumber = (page ?? 1);

 var query = Session.QueryOver<ToDo>();

 if (!string.IsNullOrWhiteSpace(searchString))
     query = query.WhereRestrictionOn(td => td.TaskName)
                      .IsInsensitiveLike(string.Format("%{0}%", searchString));

 if (!showCompleted)
     query.And(td => td.IsComplete == false);

 switch (sortOrder)
 {
    case "Name desc":
      query = query.OrderBy(td => td.TaskName).Desc;
      break;
        case "Date":
      query = query.OrderBy(td => td.DueDate).Asc;
      break;
    case "Date desc":
      query = query.OrderBy(td => td.DueDate).Desc;
      break;
    default:
      query = query.OrderBy(td => td.TaskName).Asc;
      break;
 }

 var result = query.Fetch(p=>p.Priority).Eager
           .Fetch(s=>s.Staff).Eager
           .List();

 var viewModel = AutoMapper.Mapper.Map<IEnumerable<ToDo>, 
                     IEnumerable<IndexToDoViewModel>>(result)
                     .ToPagedList(pageNumber, PageSize);
 return View(viewModel);

}

次に、ViewBag を使用してコントローラーに値を返します。たとえば、メソッドの大部分を形成するクエリsortOrderに適用する前に必要な値です。たとえば、次のようになります。NHibernate

@Html.ActionLink("Name", "Index", new {sortOrder=ViewBag.NameSortParam, 
                                      includeComplete = ViewBag.IncludeCompleted})

私のビューモデル

public class IndexToDoViewModel
{
    [DataType(DataType.Date)]
    [DisplayFormat(DataFormatString = "{0:dd MMM yyyy}")]
    [DisplayName("Date Due")]
    public DateTime? DueDate { get; set; }

    public Guid Id { get; set; }

    [DisplayName("Is Complete")]
    public bool IsComplete { get; set; }

    [DataType(DataType.MultilineText)]
    public String Notes { get; set; }

    public string Priority { get; set; }

    public string Staff {get; set;}

    [DisplayName("Name")]
    public String TaskName { get; set; }

    // These would potentially replace my ViewBag?
    public string CurrentSort { get; set; }
    public string CurrentFilter { get; set; }
    public string NameSortParam { get; set; }
    public string DateSortParam { get; set; }
    public bool IncludeCompleted { get; set; }

}
4

2 に答える 2

3

次に、ViewBag を使用して値をコントローラーに渡します。

いいえ、次のコントローラーに値を渡しています。コントローラーの新しいインスタンスがリクエストを処理するときに、ブラウザーへのラウンドトリップ後に値が (潜在的に) 使用されます。

現在のコントローラーには何も渡さないため、 ViewBag. 必要に応じて、モデルに値を入れることができます。


ビューからコントローラーにデータを送信していたとしても (これは非常に珍しいことです)、モデルを使用することは可能です。例:

MyModel viewModel = new MyModel();
ActionResult result = View(viewModel);

// here you can access anything that the view would put in the model

return result;

もちろん、ビューの前にモデルを作成する必要があるため、コントローラーでビューの値を使用してモデルを作成することはできません。ビューのデータを取得するためにビューからのデータが必要な場合は、それをコントローラーではなくモデルのメソッドとして配置します。

于 2013-03-17T23:25:13.057 に答える
1

作成するビューごとに ViewModel を作成することをお勧めします。これは、ビューにさらに多くの情報を渡す必要がある可能性が高いためです。

この場合、ページ リスト データのプロパティを持つ ViewModel があり、SortOrder の別のプロパティを追加できます。

例えば:

public class MyViewModel
{
    public IEnumerable<ToDo> TodoList { get; set; }
    public string SortOrder { get; set; }
}

SO の質問を参照してください: ViewModel のベスト プラクティス

于 2013-03-17T23:08:59.770 に答える