Quantcast
Channel: normalian blog
Viewing all articles
Browse latest Browse all 237

Knockout MVC を使ってみる

$
0
0

今回は Knockout.js を ASP.NET MVCで活用するためのライブラリである Knockout MVCを利用してみる。同ライブラリを利用することで、ASP.NET MVCでのモデルバインディングが容易になり、ASP.NET側と JavaScript側の機能連携が非常に容易になる。

インストール方法

Visual Studioから NuGet の管理コンソールを起動し、検索窓に「knockout」と入力した結果の P.3 辺りに Knockout MVCが発見できる。
f:id:waritohutsu:20140113134146j:plain

次に、Knockout.js を利用するためには ASP.NET MVCプロジェクトに対して以下の修正をする必要がある。

  • App_Start/BundleConfig
publicclass BundleConfig
{
    // バンドルの詳細については、http://go.microsoft.com/fwlink/?LinkId=301862 を参照してくださいpublicstaticvoid RegisterBundles(BundleCollection bundles)
    {
        bundles.Add(new ScriptBundle("~/bundles/jquery").Include(
                    "~/Scripts/jquery-{version}.js"));

        bundles.Add(new ScriptBundle("~/bundles/jqueryval").Include(
                    "~/Scripts/jquery.validate*"));

        bundles.Add(new ScriptBundle("~/bundles/jqueryunobtrusive").Include(
        "~/Scripts/jquery.validate.unobtrusive.js"));

        //knockout.s 用
        bundles.Add(new ScriptBundle("~/bundles/knockout").Include(
        "~/Scripts/knockout-{version}.js"));
        bundles.Add(new ScriptBundle("~/bundles/knockoutmapping").Include(
        "~/Scripts/knockout.mapping-latest.js"));

        // 以下は省略
    }
}
  • Views/Shared/_Layout.cshtml
<!DOCTYPE html><html><head>//中略</head><body>
//中略
    <divclass="container body-content">
        @RenderBody()
        <hr /><footer><p>&copy; @DateTime.Now.Year - マイ ASP.NET アプリケーション</p></footer></div>

    @Scripts.Render("~/bundles/jquery")
    @Scripts.Render("~/bundles/bootstrap")
    @Scripts.Render("~/bundles/knockout")
    @Scripts.Render("~/bundles/knockoutmapping")
    @RenderSection("scripts", required: false)
</body></html>

という感じで、Knockout.js を画面側で読みこめるように設定しておく必要がある。

簡単な使い方

以下にサンプルコードを記載してみる。

  • Person.cs Name, Age プロパティはさておき、Summary プロパティに Computed 属性を付与している点に注目していただきたい。Computed 属性を付与することで、JavaScript側にロジックを自動生成することができる。
using System.ComponentModel.DataAnnotations;
using DelegateDecompiler;

namespace KnockoutMVCSample.Models
{
    publicclass Person
    {
        [Display(Name = "名前"), Required]
        publicstring Name { get; set; }
        [Required, Display(Name = "年齢"), Range(typeof(int), "0", "200")]
        publicint Age { get; set; }

        [Computed]
        publicstring Summary
        {
            get
            {
                var ret = Name + "は";
                if (Age < 20)
                {
                    ret += "まだまだ未成熟な果実(/ω\)イヤン";
                }
                else
                {
                    ret += "熟れた果実(*´Д`)ハァハァ";
                }
                return ret;
            }
        }

        // 後述するが、 ToString を上書きすると死ぬ//public override string ToString()//{//    return string.Format("私は {0}、{1}歳☆(ゝω・)vキャピ", this.Name, this.Age);//}
    }
}
  • HomeController.cs 通常の ASP.NET MVCのコントローラであり、特に留意する点はない
using System.Web.Mvc;
using KnockoutMVCSample.Models;
using System.Diagnostics;

namespace KnockoutMVCSample.Controllers
{
    publicclass HomeController : Controller
    {
        public ActionResult Index()
        {
            return View(new Person()
            {
                Name = "幼女",
                Age = 9
            });
        }

        [HttpPost]
        public ActionResult Index(Person person)
        {
            Trace.WriteLine(string.Format("私は {0}、{1}歳☆(ゝω・)vキャピ", person.Name, person.Age));
            return View(person);
        }

        //中略
    }
}
  • Home/Index.cshtml 画面最初に Html.CreateKnockoutContext() を利用して Knockout MVC用のインスタンスを作成しており、フォーム部品を作成する際に同インスタンスを利用している点に注目してほしい
@using PerpetuumSoft.Knockout
@model KnockoutMVCSample.Models.Person

@{
    ViewBag.Title = "Home Page";
    var ko = Html.CreateKnockoutContext();
}

@using (Html.BeginForm())
{
    <br /><br /><div><h3>knockout.js でのマッピング</h3>
        @Html.LabelFor(m => m.Name) : @ko.Html.TextBox(m => m.Name, new { value = Model.Name, name = "Name" }) @Html.ValidationMessageFor(m => m.Name)<br />
        @Html.LabelFor(m => m.Age) : @ko.Html.TextBox(m => m.Age, new { value = Model.Age, name = "Age" }) @Html.ValidationMessageFor(m => m.Age)<inputid="update_button"type="button"value="年齢+1" /><br /><div>名前と年齢についてのサマリ:@ko.Html.Span(m => m.Summary, new { id = "summary" })
        </div><br /><inputtype="submit"name="submit"value="送付" /><br /></div>
}
@section scripts
{
    @ko.Apply(Model)
    <scripttype="text/javascript">        $(function(){            $('#update_button').click(function(){                $('#Age').text(viewModel.Age(viewModel.Age() + 1));});});</script>
}

更に、「注意点」のスクリーンショットを参照して頂ければわかると思うが、Knockout MVCは viewModel という変数名でモデルを生成するため、上記の記載方法で画面上で JavaScriptの viewModel を操作することができる。

注意点

Computed 属性を付与しない場合、以下の様に JavaScript側の計算用ロジックが自動生成されない。
f:id:waritohutsu:20140113134149j:plain

また、モデルクラス(今回は Person.cs) の ToString() メソッドをオーバーライドすると、以下の様に JavaScript側の自動生成コードがおかしくなってしまう点にも注意が必要だ。
f:id:waritohutsu:20140113134151j:plain

参考

Knockout MVCは以下の様にサンプルが豊富なため、こちらも参照頂きたい。


Viewing all articles
Browse latest Browse all 237

Trending Articles