入门

监控属性

使用内置绑定

控制文本和外观

绑定逻辑控制

处理表单属性

解析模板

高级应用

插件

更多信息

读取和保存JSON数据

Knockout可以实现很复杂的客户端交互,但是几乎所有的web应用程序都要和服务器端交换数据(至少为了本地存储需要序列化数据),交换数据最方便的就是使用JSON format – 大多数的Ajax应用程序也是使用这种格式。

Knockout allows you to implement sophisticated client-side interactivity, but almost all web applications also need to exchange data with the server, or at least to serialize the data for local storage. The most convenient way to exchange or store data is in JSON format - the format that the majority of Ajax applications use today.

加载或保存数据

Knockout不限制你用任何技术加载和保存数据。你可以使用任何技术和服务器来交互。用的最多的是使用jQuery的Ajax帮助,例如: getJSONpost, 和ajax。你可以通过这些方法从服务器端获取数据:

Knockout doesn’t force you to use any one particular technique to load or save data. You can use whatever mechanism is a convenient fit for your chosen server-side technology. The most commonly-used mechanism is jQuery’s Ajax helper methods, such as getJSON, post, and ajax. You can fetch data from the server:

  1. $.getJSON("/some/url", function(data) {
  2. // Now use this data to update your view models,
  3. // and Knockout will update your UI automatically
  4. })

… 或者向服务器端发送数据:

  1. var data = /* Your data in JSON format - see below */;
  2. $.post("/some/url", data, function(returnedData) {
  3. // This callback is executed if the post was successful
  4. })

或者,如果你不想用jQuery,你可以用任何其它的方式来读取或保存JSON数据。所以, Knockout需要你做的仅仅是:

Or, if you don’t want to use jQuery, you can use any other mechanism for loading or saving JSON data. So, all Knockout needs to help you do is:

  • 对于保存,让你的view model数据转换成简单的JSON格式,以方便使用上面的技术来保存数据。
  • 对于加载,更新你接收到的数据到你的view model上。
  • For saving, get your view model data into a simple JSON format so you can send it using one of the above techniques
  • For loading, update your view model using data that you’ve received using one of the above techniques

转换View Model数据到JSON格式

由于view model都是JavaScript对象,所以你需要使用标准的JSON序列化工具让转化view model为JSON格式。例如,可以使用 JSON.serialize() (新版本浏览器才支持的原生方法),或者使用 json2.js 类库。不过你的view model可能包括observables,依赖对象dependent observables和observable数组,有可能不能很好的序列化,你需要自己额外的处理一下数据。

Your view models are JavaScript objects, so in a sense, you could just serialize them as JSON using any standard JSON serializer, such as JSON.serialize() (a native function in modern browsers), or the json2.js library. However, your view models probably contain observables, computed observables, and observable arrays, which are implemented as JavaScript functions and therefore won’t always serialize cleanly without additional work on your behalf.

为了使view model数据序列化方便(包括序列化observables等格式),Knockout提供了2个帮助函数:

To make it easy to serialize view model data, including observables and the like, Knockout includes two helper functions:

  • ko.toJS — 克隆你的view model对象,并且替换所有的observable 对象为当前的值,这样你可以得到一个干净的和Knockout无关的数据copy。
  • ko.toJS — this clones your view model’s object graph, substituting for each observable the current value of that observable, so you get a plain copy that contains only your data and no Knockout-related artifacts
  • ko.toJSON — 将view model对象转化成JSON字符串。原理就是:先调在view model上调用 ko.toJS ,然后调用浏览器原生的JSON 序列化器得到结果。注:一些老浏览器版本不支持原生的JSON 序列化器(例如:IE7和以前的版本),你需要引用json2.js 类库。
  • ko.toJSON — this produces a JSON string representing your view model’s data. Internally, it simply calls ko.toJS on your view model, and then uses the browser’s native JSON serializer on the result. Note: for this to work on older browsers that have no native JSON serializer (e.g., IE 7 or earlier), you must also reference the json2.js library.

这个例子中,声明一个view model:

  1. var viewModel = {
  2. firstName : ko.observable("Bert"),
  3. lastName : ko.observable("Smith"),
  4. pets : ko.observableArray(["Cat", "Dog", "Fish"]),
  5. type : "Customer"
  6. };
  7. viewModel.hasALotOfPets = ko.computed(function() {
  8. return this.pets().length > 2
  9. }, viewModel)

该view model包含observable类型的值,依赖类型的值dependent observable以及依赖数组observable array,和普通对象。你可以像如下代码一样使用 ko.toJSON 将此转化成服务器端使用的JSON 字符串:

This contains a mix of observables, computed observables, observable arrays, and plain values. You can convert it to a JSON string suitable for sending to the server using ko.toJSON as follows:

  1. var jsonData = ko.toJSON(viewModel);
  2. // Result: jsonData is now a string equal to the following value
  3. // '{"firstName":"Bert","lastName":"Smith","pets":["Cat","Dog","Fish"],"type":"Customer","hasALotOfPets":true}'

或者,序列化之前,你想得到JavaScript简单对象的话,直接使用像这样一样使用 ko.toJS

Or, if you just want the plain JavaScript object graph before serialization, use ko.toJS as follows:

  1. var plainJs = ko.toJS(viewModel);
  2. // Result: plainJS is now a plain JavaScript object in which nothing is observable. It's just data.
  3. // The object is equivalent to the following:
  4. // {
  5. // firstName: "Bert",
  6. // lastName: "Smith",
  7. // pets: ["Cat","Dog","Fish"],
  8. // type: "Customer",
  9. // hasALotOfPets: true
  10. // }

注意 ko.toJSON 接受参数 JSON.stringify。例如,当调试Knockout应用时它可以用 “live” 来表示你的。生成一个用于此目的的很好的格式化显示,你可以传递空间参数给 ko.toJSON 来绑定你的view model:

Note that ko.toJSON accepts the same arguments as JSON.stringify. For example, it can be useful to have a “live” representation of your view model data when debugging a Knockout application. To generate a nicely formatted display for this purpose, you can pass the spaces argument into ko.toJSON and bind against your view model like:

  1. <pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

使用JSON更新View Model数据

如果你从服务器端获取数据并且更新到view model上,最简单的方式是自己实现。例如,

If you’ve loaded some data from the server and want to use it to update your view model, the most straightforward way is to do it yourself. For example,

  1. // Load and parse the JSON
  2. var someJSON = /* Omitted: fetch it from the server however you want */;
  3. var parsed = JSON.parse(someJSON);
  4. // Update view model properties
  5. viewModel.firstName(parsed.firstName);
  6. viewModel.pets(parsed.pets);

很多情况下,最直接的方法就是最简单而且最灵活的方式。当然,如果你更新了view model的属性,Knockout会自动帮你更新相关的UI元素的。

In many scenarios, this direct approach is the simplest and most flexible solution. Of course, as you update the properties on your view model, Knockout will take care of updating the visible UI to match it.

不过,很多开发人员还是喜欢使用一种好用而不是每次都写代码的方式来转化数据到view model上,尤其是view model有很多属性或者嵌套的数据结构的时候,这很有用,因为可以节约很多代码量。 the knockout.mapping 插件可以帮你做到这一点。

However, many developers prefer to use a more conventions-based approach to updating their view models using incoming data without manually writing a line of code for every property to be updated. This can be beneficial if your view models have many properties, or deeply nested data structures, because it can greatly reduce the amount of manual mapping code you need to write. For more details about this technique, see the knockout.mapping plugin.

(c) knockoutjs.com