からめもぶろぐ。

俺たちは雰囲気で OAuth をやっている

knockout.js を使って検索をしてみる

前の記事とだいぶ時間が空いてしまいましたが、引き続き knockout.js を弄ってみます。

blog.karamem0.jp

今回は検索をしてみたいと思います。

サンプル コード

Models/Person.cs

簡単な Model を作成します。

public class Person
{

    public string Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }

}

Controllers/HomeController.cs

Controller の実装は、単純に検索クエリを受け取って結果を JSON で返しています。

public class HomeController : Controller
{

    public ActionResult Index()
    {
        return this.View();
    }

    [HttpPost()]
    public JsonResult Index(string id, string name, int? age)
    {
        var data = new[]
        {
            new Person() { Id = "1", Name = "佐藤太郎", Age = 30, },
            new Person() { Id = "2", Name = "山田次郎", Age = 15, },
            new Person() { Id = "3", Name = "高橋三郎", Age = 60, },
            new Person() { Id = "4", Name = "田中四郎", Age = 55, },
            new Person() { Id = "5", Name = "鈴木五郎", Age = 45, }
        };
        return this.Json(
            data.Where(x => string.IsNullOrEmpty(id) || x.Id == id)
                .Where(x => string.IsNullOrEmpty(name) || x.Name.Contains(name)) 
                .Where(x => age == null || x.Age == age)
        );
    }

}

Views/Home/Index.cshtml

View の実装です。knockout.js を使って検索ボタンのクリックイベントに search メソッドを連結します。jQuery の serializeArray メソッドでフォームの要素を JSON にしています。

@model Karamem0.Samples.Models.Person
@{
    ViewBag.Title = "ホーム ページ";
}
@using (Html.BeginForm()) { 
    <table>
        <tr>
            <td><span class="editor-label">@Html.LabelFor(model => model.Id)</span></td>
            <td><span class="editor-field">@Html.TextBoxFor(model => model.Id)</span></td>
        </tr>
        <tr>
            <td><span class="editor-label">@Html.LabelFor(model => model.Name)</span></td>
            <td><span class="editor-field">@Html.TextBoxFor(model => model.Name)</span></td>
        </tr>
        <tr>
            <td><span class="editor-label">@Html.LabelFor(model => model.Age)</span></td>
            <td><span class="editor-field">@Html.TextBoxFor(model => model.Age)</span></td>
        </tr>
    </table>
    <input type="button" value="検索" data-bind="click: search" />
    <div data-bind="foreach: items">
        <div>
            <span data-bind="text: Id"></span>
            <span data-bind="text: Name"></span>
            <span data-bind="text: Age"></span>
        </div>
    </div>
}
<script type="text/javascript">
    $(function () {
        var viewModel = {
            items: ko.observableArray([]),
            search: function () {
                var self = this;
                var param = $("form :input").serializeArray();
                var callback = function (data) {
                    self.items.removeAll();
                    $.each(data, function (i, e) {
                        self.items.push(e);
                    });
                };
                $.post("@Url.Action("Index")", param, callback, "json");
            }
        };
        ko.applyBindings(viewModel);
    });
</script>

実行

名前で検索してみます。

ちゃんと検索できました!

ちなみに何も入れなければ全部出てきます。