1

多くのプロジェクト (名前、説明、期限など) を含む EF を使用する MVC プロジェクトがあります。また、それらに関連付けられたリージョンやアクティブな状態 (処理中、非アクティブなど) などの特定のものもあります。私がやろうとしているのは、部分ビューを介してテレリック ドロップダウン リストを使用してこれらをフィルタリングすることです。また、変更時にフィルターの最後の状態を Cookie に保存しようとしています。

私が抱えている問題は、フィルターを変更すると、変更時イベントが常に呼び出されるとは限らないことです。

インデックスは、これに含まれるアプリケーションの外部シェルをロードするために使用されます。

  1. Telerik ドロップダウンは、Viewbag と変更時イベントを使用して作成されます
  2. 部分ビューのプロジェクトを読み込む
  3. プロジェクトに関する他の 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 をビューに直接渡すのではなく、プロジェクトのビューモデル表現の実装に取り​​組んでいます。

4

1 に答える 1

1

問題を修正しました。

問題は、そのセッションで生成されたすべての部分ビューの結果に対して、デフォルトで部分ビューがキャッシュされていたことです。そのため、フィルターが変更されるたびに部分的なアクションがポストバックされることはありませんでした。部分アクションで OutputCache HTML 属性を使用して、キャッシュをより適切な時間に制限することができました。

[OutputCache(Duration=(number of seconds))] 
于 2013-07-09T17:48:58.700 に答える