none
MVCでUpdatePanelのような動作を実現するにはどうしたらいいですか? RRS feed

  • 質問

  • お世話になります。

    WebFormで以前作ったアプリをMVCを使ったものに変更(更新)しようとしています。

    WebFormの<asp:UpdatePanel ID="UpdatePanel1" runat="server" >の部分がどのように変更できるのか教えてください。

    ここで行っているのは、デスクトップアプリで言うところのメニュで3つの階層をその都度、動的に作成更新しています。

    ツリービューのような物も考えましたが、MVCだともっと複雑になりそうでした。

    比較的簡単な方法は何かありませんか?教えてください。


    【環境】
    NET Frameworkバージョンは、4.5.2、MVC5、Coreではありません。IISは、10.0Expressを使用しています。
    プロジェクトのテンプレートは、MVCの選択のみです。Windows10 VS2015

    2018年6月26日 23:05

回答

  • ASP.NET MVC には Web Forms の UpdatePanel のようなお気軽な方法はありませんが、ajax を利用しての部分更新は AjaxHelper (Ajax.ActionLink, Ajax.BeginForm)と部分ビューを使って可能です。

    > ここで行っているのは、デスクトップアプリで言うところのメニュで3つの階層をその都度、動的に作成更新しています。

    上記のところ意味が分かりませんので応用が利くかどうか不明ですが、とりあえず、Ajax.BeginForm と部分ビューを使った基本的な一例をアップしておきます。

    Html.DropDownList を使用して顧客を選択し、選択した顧客の詳細情報(部分ビュー)を AJAX を利用して <div id="results"></div> に表示するものです。

    Index2.cshtml (View)

    @{
        ViewBag.Title = "Index2";
    }
    
    <h2>Index2</h2>
    
    @using (Ajax.BeginForm(
                    "Details",
                    new AjaxOptions { UpdateTargetId = "result" }))
    {
        @Html.DropDownList(
            "id",    // これを Details(int id) のパラメータ名と合わせておくと自動的にモデルバインディングされる
            new SelectList(
                (System.Collections.IEnumerable)ViewData["customers"],
                "id",
                "name",
                6
                )
        )
        <input type="submit" value="詳細表示" />
    }
    <div id="result"></div>
    
    @section Scripts {
        @Scripts.Render("~/bundles/jqueryval")
    }


    Details.cshtml (部分 View)

    @model AdventureWorksLT.Customer
    
    <fieldset>
        <legend>Customer Details</legend>
        @Html.DisplayNameFor(model => model.Title): @Html.DisplayFor(model => model.Title)
        <br />
        @Html.DisplayNameFor(model => model.FirstName): @Html.DisplayFor(model => model.FirstName)
        <br />
        @Html.DisplayNameFor(model => model.MiddleName): @Html.DisplayFor(model => model.MiddleName)
        <br />
        @Html.DisplayNameFor(model => model.LastName): @Html.DisplayFor(model => model.LastName)
        @*<br />
        @Html.DisplayNameFor(model => model.Suffix): @Html.DisplayFor(model => model.Suffix)*@
        <br />
        @Html.DisplayNameFor(model => model.CompanyName): @Html.DisplayFor(model => model.CompanyName)
        <br />
        @Html.DisplayNameFor(model => model.SalesPerson): @Html.DisplayFor(model => model.SalesPerson)
        <br />
        @Html.DisplayNameFor(model => model.EmailAddress): @Html.DisplayFor(model => model.EmailAddress)
        <br />
        @Html.DisplayNameFor(model => model.Phone): @Html.DisplayFor(model => model.Phone)
    </fieldset>


    Controller / Action Method

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using AdventureWorksLT;
    
    namespace Mvc5App.Controllers
    {
        public class CustomerController : Controller
        {
            public ActionResult Details(int id)
            {
                var db = new AdventureWorksLTEntities();
    
                var details = (from c in db.Customer
                               where c.CustomerID == id
                               select c).FirstOrDefault();
    
                return PartialView(details);
            }
    
            public ActionResult Index2()
            {
                var db = new AdventureWorksLTEntities();
    
                var list = (from c in db.Customer
                            orderby c.CustomerID ascending
                            select new { id = c.CustomerID, name = c.Title + " " + c.FirstName + " " + c.LastName }).Take(10);
                ViewData["customers"] = list;
                return View();
            }
        }
    }

    上記のコードを実行した結果が以下の画像です。部分ビューは赤枠で囲った部分です。


    本題とは直接関係ないことですが、VS2015 の MVC のテンプレートで作ったプロジェクトで AjaxHelper が動くようにするのは設定が必要ですので注意してください。詳しくは以下の記事を見てください。

    MVC5 で AjaxHelper が働かない
    http://surferonwww.info/BlogEngine/post/2018/05/28/ajaxhelpers-do-not-work-on-mvc5-application-created-by-visual-studio-template.aspx

    他には、ASP.NET Web Forms、ASP.NET MVC に限らず Web アプリでよく行われている方法として、部分更新に必要なデータを返す Web API(アクションメソッドでも可)と jQuery.ajax を組み合わせて使っても可能です。

    • 回答としてマーク ferret001 2018年6月27日 6:02
    2018年6月27日 1:12

すべての返信

  • ASP.NET MVC には Web Forms の UpdatePanel のようなお気軽な方法はありませんが、ajax を利用しての部分更新は AjaxHelper (Ajax.ActionLink, Ajax.BeginForm)と部分ビューを使って可能です。

    > ここで行っているのは、デスクトップアプリで言うところのメニュで3つの階層をその都度、動的に作成更新しています。

    上記のところ意味が分かりませんので応用が利くかどうか不明ですが、とりあえず、Ajax.BeginForm と部分ビューを使った基本的な一例をアップしておきます。

    Html.DropDownList を使用して顧客を選択し、選択した顧客の詳細情報(部分ビュー)を AJAX を利用して <div id="results"></div> に表示するものです。

    Index2.cshtml (View)

    @{
        ViewBag.Title = "Index2";
    }
    
    <h2>Index2</h2>
    
    @using (Ajax.BeginForm(
                    "Details",
                    new AjaxOptions { UpdateTargetId = "result" }))
    {
        @Html.DropDownList(
            "id",    // これを Details(int id) のパラメータ名と合わせておくと自動的にモデルバインディングされる
            new SelectList(
                (System.Collections.IEnumerable)ViewData["customers"],
                "id",
                "name",
                6
                )
        )
        <input type="submit" value="詳細表示" />
    }
    <div id="result"></div>
    
    @section Scripts {
        @Scripts.Render("~/bundles/jqueryval")
    }


    Details.cshtml (部分 View)

    @model AdventureWorksLT.Customer
    
    <fieldset>
        <legend>Customer Details</legend>
        @Html.DisplayNameFor(model => model.Title): @Html.DisplayFor(model => model.Title)
        <br />
        @Html.DisplayNameFor(model => model.FirstName): @Html.DisplayFor(model => model.FirstName)
        <br />
        @Html.DisplayNameFor(model => model.MiddleName): @Html.DisplayFor(model => model.MiddleName)
        <br />
        @Html.DisplayNameFor(model => model.LastName): @Html.DisplayFor(model => model.LastName)
        @*<br />
        @Html.DisplayNameFor(model => model.Suffix): @Html.DisplayFor(model => model.Suffix)*@
        <br />
        @Html.DisplayNameFor(model => model.CompanyName): @Html.DisplayFor(model => model.CompanyName)
        <br />
        @Html.DisplayNameFor(model => model.SalesPerson): @Html.DisplayFor(model => model.SalesPerson)
        <br />
        @Html.DisplayNameFor(model => model.EmailAddress): @Html.DisplayFor(model => model.EmailAddress)
        <br />
        @Html.DisplayNameFor(model => model.Phone): @Html.DisplayFor(model => model.Phone)
    </fieldset>


    Controller / Action Method

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using AdventureWorksLT;
    
    namespace Mvc5App.Controllers
    {
        public class CustomerController : Controller
        {
            public ActionResult Details(int id)
            {
                var db = new AdventureWorksLTEntities();
    
                var details = (from c in db.Customer
                               where c.CustomerID == id
                               select c).FirstOrDefault();
    
                return PartialView(details);
            }
    
            public ActionResult Index2()
            {
                var db = new AdventureWorksLTEntities();
    
                var list = (from c in db.Customer
                            orderby c.CustomerID ascending
                            select new { id = c.CustomerID, name = c.Title + " " + c.FirstName + " " + c.LastName }).Take(10);
                ViewData["customers"] = list;
                return View();
            }
        }
    }

    上記のコードを実行した結果が以下の画像です。部分ビューは赤枠で囲った部分です。


    本題とは直接関係ないことですが、VS2015 の MVC のテンプレートで作ったプロジェクトで AjaxHelper が動くようにするのは設定が必要ですので注意してください。詳しくは以下の記事を見てください。

    MVC5 で AjaxHelper が働かない
    http://surferonwww.info/BlogEngine/post/2018/05/28/ajaxhelpers-do-not-work-on-mvc5-application-created-by-visual-studio-template.aspx

    他には、ASP.NET Web Forms、ASP.NET MVC に限らず Web アプリでよく行われている方法として、部分更新に必要なデータを返す Web API(アクションメソッドでも可)と jQuery.ajax を組み合わせて使っても可能です。

    • 回答としてマーク ferret001 2018年6月27日 6:02
    2018年6月27日 1:12
  • SurferOnWww様、お世話になります。

    サンプルのご呈示ありがとうございました。

    とても分かりやすく、調べることが出来ました。

    using (Ajax.BeginForm());と言うものがあったんですね。

    > MVC5 で AjaxHelper ・・

    ここもわかりやすかったですね。

    @using (Ajax.BeginForm("コントローラー内の関数", new AjaxOptions { UpdateTargetId = "result" }))
    {
        ビュー上の表示するタイミングの処理
    }
    <div id="result">ここに結果出力</div>

    2018年6月27日 6:01