多くのプロジェクト (名前、説明、期限など) を含む EF を使用する MVC プロジェクトがあります。また、それらに関連付けられたリージョンやアクティブな状態 (処理中、非アクティブなど) などの特定のものもあります。私がやろうとしているのは、部分ビューを介してテレリック ドロップダウン リストを使用してこれらをフィルタリングすることです。また、変更時にフィルターの最後の状態を Cookie に保存しようとしています。
私が抱えている問題は、フィルターを変更すると、変更時イベントが常に呼び出されるとは限らないことです。
インデックスは、これに含まれるアプリケーションの外部シェルをロードするために使用されます。
- Telerik ドロップダウンは、Viewbag と変更時イベントを使用して作成されます
- 部分ビューのプロジェクトを読み込む
- プロジェクトに関する他の Web ページの上部にナビゲーション メニューを生成します
Cookie の状態は、ページ読み込みの最初のインスタンスでここで読み取られます。
[HttpGet]
public ActionResult Index()
{
int Region_ID = -1;
int State_ID = -1;
if (this.ControllerContext.HttpContext.Request.Cookies.AllKeys.Contains("Cookie"))
{
List<string> str = this.ControllerContext.HttpContext.Request.Cookies["Cookie"].Value.Split(',').ToList<string>();
Region_ID = Convert.ToInt32(str[0]);
State_ID = Convert.ToInt32(str[1]);
}
db = new DashboardEntities();
var filterRegion = new SelectList(db.Region.Where(m => m.Active).OrderBy(n => n.Name), "ID", "Name",Region_ID).ToList();
var filterState = new SelectList(db.State.Where(m => m.Active).OrderBy(n => n.Name), "ID", "Name",State_ID).ToList();
filterRegion.Insert(0, new SelectListItem { Text = "All", Value = "-1" });
filterState.Insert(0, new SelectListItem { Text = "All", Value = "-1" });
ViewBag.FilterRegionSelectList = filterRegion;
ViewBag.FilterStateSelectList = filterState;
var prj = (db.Project.Include("Builder").Include("ProjectNotes").Where(m => m.Builder.Region_ID == Region_ID || Region_ID == -1)
.Where(m => m.State_ID == State_ID || State_ID == -1)
return View(prj);
}
パーシャルは、最初にページを読み込んだ後にフィルターの変更を表示するために使用されます。また、フィルターが変更されると、プロジェクトの正しいコレクションをリロードするときに、ここで Cookie が更新されます。
public PartialViewResult DashboardPartial(int id, int state )
{
db = new DashboardEntities();
var filterRegion = new SelectList(db.Region.Where(m => m.Active).OrderBy(n => n.Name), "ID", "Name", id).ToList();
var filterState = new SelectList(db.State.Where(m => m.Active).OrderBy(n => n.Name), "ID", "Name", state).ToList();
filterRegion.Insert(0, new SelectListItem { Text = "All", Value = "-1" });
filterState.Insert(0, new SelectListItem { Text = "All", Value = "-1" });
ViewBag.FilterRegionSelectList = filterRegion;
ViewBag.FilterStateSelectList = filterState;
HttpCookie cookie = new HttpCookie("Cookie");
cookie.Value = id.ToString() + "," + state.ToString() ;
this.ControllerContext.HttpContext.Response.Cookies.Add(cookie);
var prj = db.Project.Include("Builder").Include("ProjectNotes").Where(m => m.Builder.Region_ID == id || id == -1)
.Where(m => m.State_ID == state || state == -1);
ViewBag.Model = prj;
return PartialView(prj);
}
ビューには、変更時のイベントを処理するための JavaScript が含まれています。これを行うには、テレリック ドロップダウン リストの変更時イベントを filterChange() 関数にします。
@using Dashboard.Helpers
@{
ViewBag.Title = "Dashboard";
}
<script type="text/javascript">
function filterChange() {
$("#log").ajaxError(function (event, jqxhr, settings, exception) {
alert(exception);
});
var regionValue = $('#filterRegion').data('tDropDownList').value();
var stateValue = $('#filterState').data('tDropDownList').value();
//alert('Index: ' + regionValue.toString() + ',' + stateValue.toString());
$.get('@Url.Action("DashboardPartial")',
{ id: regionValue.toString(), state: stateValue.toString() }, function (data) {
$("#target").html(data);
});
}
</script>
<div style="width: 100%; height: 100%">
<fieldset>
<legend>Filters</legend>
<div>
@using (Html.BeginForm())
{
<div class="Filter-Div">
<div style="float: left;">
@Html.Label("Region:")
</div>
<div style="float: left;">
@Html.Telerik().DropDownList().Name("filterRegion").BindTo((List<SelectListItem>)@ViewBag.FilterRegionSelectList).ClientEvents(events => events.OnChange("filterChange"))
</div>
</div>
<div class="Filter-Div">
<div style="float: left;">
@Html.Label("Project State:")
</div>
<div style="float: left;">
@Html.Telerik().DropDownList().Name("filterState").BindTo((List<SelectListItem>)@ViewBag.FilterStateSelectList).ClientEvents(events => events.OnChange("filterChange"))
</div>
</div>
<div class="Filter-Div">
<table class="noborder">
<tr class="noborder"> <input type="submit" value="Export" name="btnName" /> </tr>
</table>
</div>
}
</div>
</fieldset>
@(Html.Telerik().ScriptRegistrar()
.DefaultGroup(group => group
.Add("telerik.common.js")
.Add("telerik.tabstrip.min.js")
.Add("telerik.calendar.min.js"))
.jQuery(false))
<div>
@if (User.IsInRole("SuperUser") || User.IsInRole("Admin"))
{
@Html.ActionLink("Create New", "Create", new { controller = "Dashboard", page = "Index" }, new { @class = "t-button" })
}
</div>
</div>
<div id="target">
@{ Html.RenderPartial("DashboardPartial");
}
</div>
私は MVC とエンティティ フレームワークを初めて使用するので、とにかくコードを改善する方法がある場合は注意してください。ご協力ありがとうございます。
サイドノート - 現在、EF をビューに直接渡すのではなく、プロジェクトのビューモデル表現の実装に取り組んでいます。