【ASP.NET MVC】【VB.NET】ASP.NET MVC で、 knockout.js を使う ~基本編~ [2]

はじめに

http://miso-soup3.hateblo.jp/entry/2013/07/18/141908
を参考に、セレクトボックス同士が連動したサイトを、VB.NETで作ってみた

サンプル

 * 国を選んだら、会社リストが出てくるものを作る

モデル

* CompanyModel.vb
Namespace Models

    Public Class CompanyModel
        Public Property CountryId As String
        Public Property CompanyId As String
    End Class

End Namespace

コントローラ

* SampleKnockoutController.vb
Imports System.Web.Mvc
Imports WebAppli.Models

Namespace Controllers
    Public Class SampleKnockoutController
        Inherits Controller

        Private CompanyInfoDictinary As Dictionary(Of String, List(Of ListItem))

        Public Sub New()
            CompanyInfoDictinary = New Dictionary(Of String, List(Of ListItem)) From
                {
                {"JP", New List(Of ListItem) From
                {
                New ListItem() With {.Value = "J01", .Text = "Sony"},
                New ListItem() With {.Value = "J02", .Text = "Hitachi"},
                New ListItem() With {.Value = "J03", .Text = "Toshiba"},
                New ListItem() With {.Value = "J04", .Text = "Fujitsu"}
            }
            },
            {"US", New List(Of ListItem) From
            {
               New ListItem() With {.Value = "U01", .Text = "Google"},
               New ListItem() With {.Value = "U02", .Text = "Yahoo"},
               New ListItem() With {.Value = "U03", .Text = "Microsoft"}
            }
            }
            }
        End Sub

        Function SampleView() As ActionResult
            Return View()
        End Function

        <HttpGet>
        Function GetCountries() As ActionResult
            Dim jsonData = New List(Of ListItem) From
                {
                    New ListItem() With {.Value = "JP", .Text = "Japan"},
                    New ListItem() With {.Value = "US", .Text = "USA"}
                }
            Return Json(jsonData, JsonRequestBehavior.AllowGet)
        End Function

        <HttpGet>
        Function GetCompanies(ByVal countryId As String) As ActionResult
            Dim jsonData = Me.CompanyInfoDictinary(countryId)
            Return Json(jsonData, JsonRequestBehavior.AllowGet)
        End Function

        <HttpPost>
        Function SendComapnyData(ByVal model As CompanyModel) As ActionResult
            Return View(model)
        End Function

    End Class
End Namespace

ビュー

* SampleView.vbhtml
@ModelType WebAppli.Models.CompanyModel

@Code
    ViewData("Title") = "SampleView"
End Code

<h2>SampleView</h2>

@Using (Html.BeginForm("SendComapnyData", "SampleKnockout", FormMethod.Post))
@<table>
    <thead>
        <tr>
            <th width ='45%'>国コード</th>
            <th width='45%'>会社</th>
            <th width ='10%'> </th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>
                <select data-bind='options: countries, optionsText: "Text", optionsValue: "Value",
                        value: selectedCountry, optionsCaption: "選択..."'
                        name="@Html.NameFor(Function(model) model.CountryId)"> </select>
            </td>
            <td>
                <select data-bind="options: comapanies, optionsText: 'Text', optionsValue: 'Value',
                        value: selectedCompany, optionsCaption: '選択...', enable: comapanies().length !== 0"
                        name="@Html.NameFor(Function(model) model.CompanyId)"></Select>
            </td>
            <td>
                <input type="submit" value="Send" />
            </td>
                                                                                            </tr>
    </tbody>
</table>
End Using

<script src = "@Url.Content("~/Scripts/jquery-1.10.2.js")" type="text/javascript"></script>
<script src = "@Url.Content("~/Scripts/knockout-3.4.0.debug.js")" type="text/javascript"></script>
<script type = "text/javascript" >
    $(function () {
        var sampleViewModel = {
            countries: ko.observableArray([]),
            comapanies: ko.observableArray([]),
            selectedCountry: ko.observable(),
            selectedCompany: ko.observable(),
            setCountries: function () {
                // 国コード(第一セレクトボックス)のデータ取得
                $.ajax({
                    type: 'GET',
                    url: '@Url.Action("GetCountries")', // アクセス先のURL
                    dataType: 'json',
                    cache: false,
                    success: function (data) {
                        sampleViewModel.countries(data);
                    }
                });
            }
        }
 
        sampleViewModel.selectedCountry.subscribe(function (selectedCountryId) {
            if(!selectedCountryId) {
                sampleViewModel.comapanies([]);
            }

            // 会社コード(第二セレクトボックス)のデータ取得
            $.ajax({
                type: 'GET',
                url: '@Url.Action("GetCompanies")', // アクセス先のURL
                data: { countryId: selectedCountryId },
                dataType: 'json',
                cache: false,
                success: function (data) {
                    sampleViewModel.comapanies(data);
                    sampleViewModel.selectedCompany('');
                }
            });
        });

        ko.applyBindings(sampleViewModel);
        sampleViewModel.setCountries();
    });
</script>
* SendComapnyData.vbhtml
@ModelType WebAppli.Models.CompanyModel

@Code
    ViewData("Title") = "SendComapnyData"
End Code

<h2>SendComapnyData</h2>

<p>CountryId : @Model.CountryId </p>
<p>CompanyId : @Model.CompanyId </p>

補足

subscribe

 * 値が変化した際のイベントハンドラを設定できる
http://qiita.com/MKGaru/items/948e8a5b7b9f2063c1a4

関連記事

ASP.NET MVC で、 knockout.js を使う ~入門編~

http://blogs.yahoo.co.jp/dk521123/35660898.html

ASP.NET MVC で、 knockout.js を使う ~基本編~ [1]

http://blogs.yahoo.co.jp/dk521123/35669223.html