🔄
knockout.js でページの再読み込みに対応する
はじめに
前回の記事の続きです。
前回の状態だと、ページを再読み込みすると、検索結果がすべて消えて初期状態に戻ってしまうという問題点がありました。それではやはり使い勝手が悪いので、修正してみます。簡単に言ってしまうと、データをどこかに保存しておけばいいのですが、今回はサーバー側に保存します。
実行手順
Controllers/HomeController.cs
前回からの変更点として、検索されたときにパラメーターをセッションに入れているのと、初期表示でセッションにデータがあれば ViewBag
に入れるところが追加されています。
public class HomeController : Controller
{
public ActionResult Index()
{
// セッションがあれば ViewBag に入れる
var person = this.Session["Person"] as Person;
if (person != null)
{
this.ViewBag.Person = person;
}
return View();
}
[HttpPost()]
public JsonResult Index(Person person)
{
// パラメーターをセッションに格納する
this.Session["Person"] = person;
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(person.Id) || x.Id == person.Id)
.Where(x => string.IsNullOrEmpty(person.Name) || x.Name.Contains(person.Name))
.Where(x => person.Age == null || x.Age == person.Age)
);
}
}
Views/Home/Index.cshtml
ViewBag
に入れられたパラメーターを Json.Encode
ヘルパーメソッドで JavaScript から読めるようにします。あとはそれをフォームに突っ込んで再検索します。
<script type="text/javascript">
$(function () {
var viewModel = {
items: ko.observableArray([]),
search: function () {
var self = this;
var param = {};
$("form :input").each(function () {
var name = $(this).attr("name");
var val = $(this).val();
param[name] = val;
});
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);
// ViewBag からデータをもらう
var person = @Html.Raw(Json.Encode(ViewBag.Person));
if (person != null) {
// フォームにデータを入れる
$("form :input").each(function () {
var name = $(this).attr("name");
var val = person[name];
if (val != null) {
$(this).val(val);
}
});
// 再検索
viewModel.search();
}
});
</script>
おわりに
これで再読み込みをしても元の状態を復元できました。
Discussion