Knockout, JavaScript Model-View-ViewModel

Table of Contents

1 Knockout简介

Knockout (KO) is a JavaScript library that helps you to create rich, responsive display and editor user interfaces with a clean underlying data model. Any time you have sections of UI that update dynamically (e.g., changing depending on the user’s actions or when an external data source changes), KO can help you implement it more simply and maintainably.

Developers familiar with Ruby on Rails, ASP.NET MVC, or other MV* technologies may see MVVM as a real-time form of MVC with declarative syntax. In another sense, you can think of KO as a general way to make UIs for editing JSON data … whatever works for you.

使用KO可以简化前端开发。比如,我们要把后端返回的JSON数据展示到Html表格中,如何实现呢?如果不使用框架,你可以通过循环遍历JSON数据,在遍历数据的同时构造出<tr>和<td>标签,每构造完一行就加到<table>中直到遍历数据结束。如果使用KO框架,用 foreach binding 可以更加方便地实现相同的功能(后文有这个例子更详细的介绍),这简化了编程。当然,Knockout还有很多优秀的替代品,如 Vue.js, AngularJS 等等。

参考:
Knockout Documentation: http://knockoutjs.com/documentation/introduction.html

2 KO简单例子

参考:
Knockout Tutorials: http://learn.knockoutjs.com
Knockout Live examples: http://knockoutjs.com/examples/

2.1 第一个例子:基本使用

下面代码很简单,首先给出不使用Knockout时的例子。

<body>
  <p>First name: <strong>Bert</strong></p>
  <p>Last name: <strong>Bertington</strong></p>
</body>

下面是和前面效果相同,但使用Knockout的例子。

<head>
  <script src="http://cdn.bootcss.com/knockout/3.4.0/knockout-min.js" type="text/javascript"></script>
</head>
<body>
  <!-- This is a *view* - HTML markup that defines the appearance of your UI -->
  <p>First name: <strong data-bind="text: firstName"></strong></p>
  <p>Last name: <strong data-bind="text: lastName"></strong></p>

  <script>
  // This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
  function AppViewModel() {
    this.firstName = "Bert";
    this.lastName = "Bertington";
  }

  // Activates knockout.js
  ko.applyBindings(new AppViewModel());
  </script>
</body>

首先在strong标签中增加“data-bind”属性(这不是html标准属性,Knockout负责解析这个属性),再定义相应的“viewmodel”,最后调用ko.applyBindings应用数据绑定即可。
这个例子只是演示Knockout基本使用,过于简单,体现不了Knockout的优势。

2.2 第二个例子:自动更新控件数据

下面是Knockout的另一个例子。

<head>
  <script src="http://cdn.bootcss.com/knockout/3.4.0/knockout-min.js" type="text/javascript"></script>
</head>
<body>
  <!-- This is a *view* - HTML markup that defines the appearance of your UI -->
  <p>First name: <input data-bind="value: firstName" /></p>
  <p>Last name: <input data-bind="value: lastName" /></p>
  <p>Full name: <strong data-bind="text: fullName"></strong></p>

  <script>
  // This is a simple *viewmodel* - JavaScript that defines the data and behavior of your UI
  function AppViewModel() {
    this.firstName = ko.observable("Bert");
    this.lastName = ko.observable("Bertington");

    this.fullName = ko.computed(function() {
        return this.firstName() + " " + this.lastName();
    }, this);
  }

  // Activates knockout.js
  ko.applyBindings(new AppViewModel());
  </script>
</body>

两个输入框中的数据任何一个发生了变化,都会看到“Full name”处显示的结果会自动更新。
实现相同的效果,如果不使用Knockout,则我们可能需要注册onchange事件,并通过getElementById找到需要更新的元素。使用Knockout的话,这些代码都省略了。

knockout_ex1.png

Figure 1: Knockout更新数据

2.3 第三个例子:绑定数据到表格

本节的例子演示了如何绑定JSON数据到Html表格。

下面是不使用KO时的做法:

<head>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.0/jquery.min.js" type="text/javascript"></script>
</head>

<body>
  <table>
    <tr>
      <th>User Name</th>
      <th>Score</th>
      <th>Team</th>
    </tr>
  </table>

  <script type="text/javascript">
   $(document).ready(function () {
     // get json data from server, here just dummy data
     var json = [{"User_Name":"John Doe","score":"10","team":"1"},
                 {"User_Name":"Jane Smith","score":"15","team":"2"},
                 {"User_Name":"Chuck Berry","score":"12","team":"2"}];
     var tr;
     for (var i = 0; i < json.length; i++) {
       tr = $('<tr/>');
       tr.append("<td>" + json[i].User_Name + "</td>");
       tr.append("<td>" + json[i].score + "</td>");
       tr.append("<td>" + json[i].team + "</td>");
       $('table').append(tr);
    }
   });
  </script>
</body>

使用KO的foreach binding则更加方便。如:

<head>
  <script src="http://cdn.bootcss.com/knockout/3.4.0/knockout-min.js" type="text/javascript"></script>
</head>

<body>
  <table>
    <tr>
      <th>User Name</th>
      <th>Score</th>
      <th>Team</th>
    </tr>
    <tbody data-bind="foreach: teams">
      <tr>
        <td data-bind="text: User_Name"></td>
        <td data-bind="text: score "></td>
        <td data-bind="text: team "></td>
      </tr>
    </tbody>
  </table>

  <script type="text/javascript">
   // get json data from server, here just dummy data
   var json = [{"User_Name":"John Doe","score":"10","team":"1"},
               {"User_Name":"Jane Smith","score":"15","team":"2"},
               {"User_Name":"Chuck Berry","score":"12","team":"2"}];
   ko.applyBindings({ teams: json });
  </script>
</body>

参考:http://stackoverflow.com/questions/17066636/parsing-json-objects-for-html-table


Author: cig01

Created: <2016-05-29 Sun 00:00>

Last updated: <2017-05-10 Wed 22:10>

Creator: Emacs 25.1.1 (Org mode 9.0.7)