KnockoutJS 3.X API 第七章 其他技术(1) 加载和保存JSON数据

时间:2022-03-14 21:10:00

Knockout允许您实现复杂的客户端交互性,但几乎所有Web应用程序还需要与服务器交换数据,或至少将本地存储的数据序列化。 最方便的交换或存储数据的方式是JSON格式 - 大多数Ajax应用程序今天使用的格式。

加载或保存数据

Knockout不强制您使用任何一种特殊技术来加载或保存数据。 您可以使用任何适合您所选择的服务器端技术的机制。 最常用的机制是jQuery的Ajax方法,例如getJSON,post和ajax。 您可以从服务器获取数据:

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

或者您可以向服务器发送数据:

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

或者,如果您不想使用jQuery,则可以使用任何其他机制来加载或保存JSON数据。 所以,所有Knockout需要帮助你做的是:

  • 要保存,请将您的视图模型数据转换为简单的JSON格式,以便可以使用上述其中一种技术发送它
  • 要加载,请使用您通过上述其中一种方法收到的数据更新视图模型

将视图模型数据转换为纯JSON

您的视图模型是JavaScript对象,因此在某种意义上,您可以使用任何标准JSON序列化程序(例如JSON.stringify(现代浏览器中的本地函数)或json2.js library)将它们序列化为JSON。 但是,您的视图模型可能包含observables,computed observables和observable数组,这些数组实现为JavaScript函数,因此不会在不执行额外工作的情况下完全序列化。

为了便于序列化视图模型数据,包括observables等,Knockout包括两个帮助函数:

  • ko.toJS — 这克隆了你的视图模型的对象图,用每个observable替换了observable的当前值,所以你得到一个只包含你的数据和没有Knockout相关的工件
  • ko.toJSON — 这将生成一个JSON字符串,表示您的视图模型的数据。 在内部,它简单地在您的视图模型上调用ko.toJS,然后在结果上使用浏览器的原生JSON序列化程序。 注意:为了在没有本地JSON序列化器(例如,IE 7或更早版本)的旧版浏览器上工作,还必须引用json2.js库。

例如,定义视图模型如下:

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

它包含可观察量,计算可观察量,可观察数组和平均值的混合。 您可以将其转换为适用于使用ko.toJSON发送到服务器的JSON字符串,如下所示:

ar jsonData = ko.toJSON(viewModel);

// Result: jsonData is now a string equal to the following value
// '{"firstName":"Bert","lastName":"Smith","pets":["Cat","Dog","Fish"],"type":"Customer","hasALotOfPets":true}'

或者,如果您只想在序列化之前使用纯JavaScript对象图,请使用ko.toJS如下:

var plainJs = ko.toJS(viewModel);

// Result: plainJS is now a plain JavaScript object in which nothing is observable. It's just data.
// The object is equivalent to the following:
// {
// firstName: "Bert",
// lastName: "Smith",
// pets: ["Cat","Dog","Fish"],
// type: "Customer",
// hasALotOfPets: true
// }

注意,ko.toJSON接受与JSON.stringify相同的参数。 例如,在调试Knockout应用程序时,对视图模型数据进行“实时”表示是非常有用的。 要为此目的生成格式良好的显示,可以将空格参数传递给ko.toJSON并绑定到视图模型,如:

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

使用JSON更新视图模型数据

如果您从服务器加载了一些数据,并希望使用它来更新您的视图模型,最直接的方法是:

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

在许多情况下,这种直接方法是最简单和最灵活的解决方案。 当然,当您更新视图模型上的属性时,Knockout将会更新可见的UI来匹配它。

然而,许多开发人员更喜欢使用更多的基于约定的方法来使用传入数据更新他们的视图模型,而不需要为每个要更新的属性手动编写一行代码。 如果您的视图模型具有许多属性或深层嵌套的数据结构,这可能是有益的,因为它可以大大减少您需要编写的手动映射代码的数量。 有关此技术的更多详细信息,请参阅以后章节的knockout.mapping插件。