さっしーブログ

埼玉県在住のシステムエンジニアです。基本的には技術的な内容を中心に発信していきます。

knockout.js チュートリアル 【Loading and saving data】

目次

本記事はknockout.jsの公式サイトにある以下のチュートリアルを実施した備忘録です。 learn.knockoutjs.com

Step2

タスクリストのサンプルプログラム(JSONデータ読み込み)

サンプルコード

$.getJSON()によりJSONデータをロードして、そこから各taskのインスタンスを生成してタスクリストを構築している。

【注意】 以下のjsコードはjsonファイルのデータを$.getJSONを使用して読み込んでいるためChromeでは動かないのでChrome以外のブラウザでご確認ください。

sample.html

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<script type="text/javascript" src="../../lib/knockout-3.2.0.js"></script>
<script type="text/javascript" src="sample.js" defer="defer"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<title></title>
</head>
<body>
<h3>Tasks</h3>
<form data-bind="submit: addTask">
  タスク追加: <input data-bind="value: newTaskText" placeholder="What needs to be done?" />
  <button type="submit">追加する</button>
</form>
<ul data-bind="foreach: tasks, visible: tasks().length > 0">
  <li>
  <input type="checkbox" data-bind="checked: isDone" />
  <input data-bind="value: title, disable: isDone" />
  <a href="#" data-bind="click: $parent.removeTask">Delete</a>
  </li>
</ul>
現在 <b data-bind="text: incompleteTasks().length">&nbsp;</b> タスク
<span data-bind="visible: incompleteTasks().length == 0"> - さて、一息入れましょう!!</span>
</body>
</html>

sample.js

function Task(data) {
  this.title = ko.observable(data.title);
  this.isDone = ko.observable(data.isDone);
}

function TaskListViewModel() {
  var self = this;
  self.tasks = ko.observableArray([]);
  self.newTaskText = ko.observable();
  self.incompleteTasks = ko.computed(function() {
    return ko.utils.arrayFilter(self.tasks(), function(task) { return !task.isDone() });
  });

  // Operations
  self.addTask = function() {
    self.tasks.push(new Task({ title: this.newTaskText() }));
    self.newTaskText("");
  };
  self.removeTask = function(task) { self.tasks.remove(task) };

  $.getJSON("tasks.json", function(allData){
    var mappedTasks = $.map(allData, function(item){
      return new Task(item);
    });
    self.tasks(mappedTasks);
  });
}

ko.applyBindings(new TaskListViewModel());

tasks.json

{
  "1":{
     "title":"test1",
     "isDone":true
  },
  "2":{
    "title":"test2",
    "isDone":true
  },
  "3":{
    "title":"test3",
    "isDone":false
  },
  "4":{
    "title":"test4",
    "isDone":false
  },
  "5":{
    "title":"test5",
    "isDone":false
  }
}

Step3

タスクリストのサンプルプログラム(フォームでのデータ送信版)

サンプルコード

ko.toJSON()でモデルデータをJSONに変換することができる。 ※本サンプルコードは実際に送信はできないためご了承ください。

【注意】 以下のjsコードはjsonファイルのデータを$.getJSONを使用して読み込んでいるためChromeでは動かないのでChrome以外のブラウザでご確認ください。

sample.html

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <script type="text/javascript" src="../../lib/knockout-3.2.0.js"></script>
    <script type="text/javascript" src="sample.js" defer="defer"></script>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
    <title></title>
  </head>
  <body>
    <h3>Tasks</h3>
    <form data-bind="submit: addTask">
      タスク追加: <input data-bind="value: newTaskText" placeholder="What needs to be done?" />
      <button type="submit">追加する</button>
    </form>
    <ul data-bind="foreach: tasks, visible: tasks().length > 0">
      <li>
        <input type="checkbox" data-bind="checked: isDone" />
        <input data-bind="value: title, disable: isDone" />
        <a href="#" data-bind="click: $parent.removeTask">Delete</a>
      </li>
    </ul>

    現在 <b data-bind="text: incompleteTasks().length">&nbsp;</b> タスク
    <span data-bind="visible: incompleteTasks().length == 0"> - さて、一息入れましょう!!</span>

    <form action="/tasks/saveform" method="post">
      <textarea type="hidden" name="tasks" data-bind="value: ko.toJSON(tasks)"></textarea>
      <button type="submit">Save</button>
    </form>
  </body>
</html>

sample.js

function Task(data) {
  this.title = ko.observable(data.title);
  this.isDone = ko.observable(data.isDone);
}

function TaskListViewModel() {
  // Data
  var self = this;
  self.tasks = ko.observableArray([]);
  self.newTaskText = ko.observable();
  self.incompleteTasks = ko.computed(function() {
    return ko.utils.arrayFilter(self.tasks(), function(task) { return !task.isDone() });
  });

  // Operations
  self.addTask = function() {
  self.tasks.push(new Task({ title: this.newTaskText() }));
  self.newTaskText("");
  };
  self.removeTask = function(task) { self.tasks.remove(task) };

  $.getJSON("tasks.json", function(allData){
    var mappedTasks = $.map(allData, function(item){
      return new Task(item);
    });
    self.tasks(mappedTasks);
  });
}

ko.applyBindings(new TaskListViewModel());

tasks.json

{
  "1":{
    "title":"test1",
    "isDone":true
  },
  "2":{
    "title":"test2",
    "isDone":true
  },
  "3":{
    "title":"test3",
    "isDone":false
  },
  "4":{
    "title":"test4",
    "isDone":false
  },
  "5":{
    "title":"test5",
    "isDone":false
  }
}

Step4

タスクリストのサンプルプログラム(ajaxでのデータ送信版)

サンプルコード

タグを使用せず、