私は SearchViewModel を持っています:
public class SearchViewModel
{
[Required]
public DateTime From { get; set; }
[Required]
public int Days { get; set; }
public long DealerID { get; set; }
public IQueryable<TypesAvail> TypesAvails { get; set; }
}
IQueryable TypesAvails は別のクラスで、DealerID から、および SearchviewModel クラスの From プロパティと Days プロパティの間で利用可能な CarTypes のリストを保持します。ビューでドロップダウンリストを生成するためにも使用されます。
public class TypesAvail
{
public String TypeNme { get; set; }
public long TypeID { get; set; }
public int NumSelected { get; set; }
public int TypeCount { get; set; }
public IEnumerable<SelectListItem> CarsAvail
{
get
{
return new SelectList(
Enumerable.Range(0, TypeCount+1)
.OrderBy(typecount => typecount)
.Select(typecount => new SelectListItem
{
Value = typecount.ToString(),
Text = typecount.ToString()
}), "Value", "Text");
}
}
}
私のコントローラーは:(編集:データにアクセスするコードを表示するコントローラーを追加)
public ActionResult Avail(SearchViewModel model, string id)
{
if (ModelState.IsValid)
{
var dteFrom = model.From;
var dteTo = model.From.AddDays(model.Days);
var prebookedCars = db.Cars
.Where(car=> car.Rentals.Any(rental =>
(model.DealerID == rental.Dealerid) && (
(dteFrom >= rental.dateout && dteFrom < rental.datein )
||
(dteTo > rental.dateout && dteTo <= rental.datein )
||
(dteFrom <= rental.dateout && dteTo >= rental.datein )
)));
model.TypesAvails = db.Cars
.Where(r => r.Dealerid == model.DealerID)
.Except(prebookedCars)
.GroupBy(p => p.CarType)
.Select(g => new TypesAvail
{
TypeNme = g.Key.type_name,
TypeID = g.Key.type_id,
TypeCount = g.Count(),
NumSelected = 0
}
);
return View(model);
}
else
{
return View(model);
}
}
ロジック(私は修正する必要があります)は次のとおりです。
- SearchViewModel は、TypesAvail に対して null でビューに送信されます
Post が発生すると、コントローラーは From、Days、および DealerID をモデルに直接入力し、以下を使用します。
[HttpPost]
public ActionResult Avail(SearchViewModel model)
コントローラーでは、TypesAvail IQueryable にもデータを入力します。
これで、ViewModel には検索日、日数、および選択リストを含む TypesAvailable のリストが含まれるようになりました。
これは、次のようにビューに再入力されます。
@model ebm2.ViewModels.SearchViewModel
@using (Html.BeginForm())
{
@Html.ValidationSummary()
<ul data-role="listview" data-inset="true">
<li data-role="list-divider">Check Availability</li>
<li data-role="fieldcontain">
@Html.LabelFor(m => m.From)
@Html.TextBoxFor(m => m.From, new { @type = "date", data_role = "datebox", data_options = "{\"mode\":\"slidebox\", \"overrideDateFormat\":\"%A %d %b %Y\"}" })
@Html.ValidationMessageFor(m => m.From)
</li>
<li data-role="fieldcontain">
@Html.LabelFor(m => m.Days)
@Html.TextBoxFor(m => m.Days, new { @type = "range", min = 1, max = 30 })
@Html.ValidationMessageFor(m => m.Days)
</li>
<li data-role="fieldcontain">
<input type="submit" value="Search" />
</li>
</ul>
@Html.HiddenFor(m => m.DealerID)
if (Model.TypesAvails != null)
{
<ul data-role="listview" data-inset="true">
<li data-role="list-divider">Book</li>
@foreach (var item in Model.TypesAvails)
{
<li data-role="fieldcontain">
@Html.HiddenFor(modelItem => item.TypeID) ->
@Html.DisplayFor(modelItem => item.NumSelected) ->
@Html.DropDownListFor(modelItem => item.NumSelected, item.CarsAvail)
</li>
}
</ul>
}
}
サーバーへの 2 回目の POST は次のように表示されます。
From=07%2F08%2F2012+00%3A00%3A00& Nights=1 & DealerID=1 &
item.TypeID=3059 & item.NumSelected=3 &
item.TypeID=3103 & item.NumSelected=2 &
item.TypeID=3170 & item.NumSelected=7 &
item.TypeID=3212 & item.NumSelected=4
それらを表示するRazorは、TypeIDをそれぞれのドロップダウンリストに割り当てていません:
@Html.HiddenFor(modelItem => item.TypeID)
@Html.DropDownListFor(modelItem => item.NumSelected, item.CarsAvail)
私の質問は、モデルの POST からです - TypesAvail の場合は NULL を示しています - ドロップダウン リストで選択した項目をポストバックの ViewModel に直接表示する方法はありますか?
そうでない場合、FORMフィールドをループして別のモデルを作成するにはどうすればよいですか-次のようになります。
From
Days
DealerID
{
TypeID = 3059, NumSelected = 3,
TypeID = 3103, NumSelected = 2,
TypeID = 3170, NumSelected = 7,
TypeID = 3212, NumSelected = 4
}
...これを使用して、データベースにレコードを追加できます (基本的には、ディーラーが 2 つの日付の間にレンタルしたい車のリスト)。
または、1 つのフォームから検索日付を取得しようとしていて、同じフォームに複数のドロップダウンリストを入力して、やりすぎているのですか?もっと良い方法はありますか?
- 日付ボックスと泊数から探す
- 次に、検索基準を満たすオプションのリストを表示します
- 次に、サーバーに投稿し、検索データ (日付、日数、ディーラー ID から)、および選択したドロップダウン リストを保存し、それぞれで何が選択されましたか?
ありがとう、マーク
アップデート
Shyu の助けを借りて、私はいくつかの進歩を遂げました - エディターテンプレートを追加しました:
@model ebm2.Models.TypesAvail
@Html.DropDownListFor(modelItem => modelItem.NumSelected, Model.CarsAvail)
...そして、これを次のようにビューにレンダリングしました:
@Html.EditorFor(model=>model.TypesAvails)
ただし、フォームをコントローラーに戻すと (editorTemplate を追加した後)、次のメッセージが表示されます。
[MissingMethodException: Cannot create an instance of an interface.]
これは、モデルが認識されなくなったことを意味していると思いますが、これは EditorTemplate が原因ですか?
ポストバックしてからViewModelに追加するのが私のアプローチですか、これを行うための最良の方法ですか、それともjQuery/Ajaxを使用してすべてクライアント側で行うことをお勧めしますか?そして、完成したJSONがあるときに最終的にサーバーにポストバックするだけです私のモデルのオブジェクト?
これに関するガイダンスをいただければ幸いです。
ありがとう、マーク