miso_soup3 Blog

主に ASP.NET 関連について書いています。

knockout.js リストのバインディング

knockout.js を使って ajax 通信を使ったリストのバインディングを行う方法です。
既にいろんなところに情報がありますが、覚書きとして・・

ダウンロード

公式の knockout.js からDLまたは、nuget で

Install-Package knockoutjs

Html

とあるボタンが押されたら、ニュースを取得してリストに表示する、という実装を行います。

Html は以下の通りです。

<div 
 class="view-news" 
 data-get-url="<%= Url.Action("GetNews", "NewsApi") %>">
  クリックでニュースを表示します。
</div>

<ul data-bind="foreach: newsList" class="news-list">
 <li data-bind="attr: { 'data-id' : Id }">
  <div data-bind="text: DateText"></div>
  <div data-bind="text: Content"></div>
 </li>
</ul>
属性のバインディング

属性の値にバインドしたい時は、下のように書きます。
属性名を独自の名前にしたい場合は、'' で囲む必要があります。

data-bind="attr: { 'data-id' : Id }"

公式のThe attr bindingに説明があります。

Json を提供する API を用意

ASP.NET MVC で用意しました。
本当は MVC4 の WEB API を使いたいところですが、プロジェクトのバージョンが古かったので(; ;) 、普通のアクションメソッドで作成しました。

/// <summary>
/// ニュースを取得します
/// </summary>
/// <param name="maxCount"></param>
/// <returns></returns>
[HttpGet]
[Authorize]
public ActionResult GetNews(int maxCount)
{
	var response = _newsService.GetNews(maxCount);
	return Json(response.News, JsonRequestBehavior.AllowGet);
}

GET で Json を取得するときは、JsonRequestBehavior.AllowGet の指定を忘れがち。。
取得できる Json は、このような感じです。

[{"Id":41,"DateText":"12/21(金)","Content":"今日ReSharperを買いました!"},{...//続く}]

各項目名は、Html で書いた
data-bind="text: DateText"(←例えばこのDateText)
の名前と同じにします。

JavaScript

JavaScript 以下の通りです。

$(function () {
 function viewModel() {
  var self = this;
  self.newsList = ko.observableArray();
 }

 var viewModel = new viewModel();

 ko.applyBindings(viewModel);

 $(".view-news").live('click', function () {
  //ニュースを表示するボタンがクリックされたら

  //APIを取得するためのURLを取得
  var url = $(this).attr("data-get-url");

  $.ajax({
   type: "GET",
   url: url,
   data: { maxCount: 5 },
   dataType: "json",
   cache: false,
   success: function (data) {
    viewModel.newsList(data);
   }
 });

});

viewModel の newsList という名前は、Html で ul 要素に書いた
data-bind="foreach: newsList" (←例えばこの newsList)
名前と同じにします。

$(...).live(...) という書き方は古いみたいですが、
$(...)on(...) でかくと、新しく生成された要素に対しては適応されず・・・。
適応されます。$(document).on('click',要素,function() {... という書き方をすると、新しく生成された要素にも適応します。参照:jQuery 1.7の on() off()について調べてみた

おしまい

2012年12月14日に、公式サイトを日本語訳したKnockout 日本語ドキュメント
というサイトが公開されています!便利!