Knockoutjs实战开发:JSON数据的加载和保存(Loading and Saving JSON data)
Knockoutjs可以帮助我们实现复杂的客户端交互,但是在很多的时候我们需要和我们的服务器进行数据交互或者至少将数据序列化到我们的本地存储器。此时我们就可以使用JSON格式数据进行数据的交互和保存了。
一、加载和保存数据。
Knockoutjs并不强制要求我们使用某个具体的技术来进行数据的读取和保存,我们可以根据自己的需要使用不同的技术,我们经常使用的是JQuery的Ajax方式,比如:getJSON、post和ajax等,我们可以使用下面的方法从服务器取得数据:
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的话,你也可以使用其他的技术来取得和发送数据,无论如何,Knockoutjs可以帮助你做如下的两件事情:
(1)、保存数据:Knockoutjs可以将View Model中的数据保存到JSON中,这样你就可以使用相应的技术将数据传到服务器进行保存。
(2)、加载数据:Knockoutjs将你取得到的数据传送到对应的View Model,从而改变View Model层的数据,这样你的页面展示的数据也会随之改变了。
二、将View Model层数据转换成JSON数据。
我们的View Model是一个个的JavaScript对象,所以在某种意义上,我们可以使用JSON的序列化函数将此转换为JSON数据,比如:JSON.serialize()
(现在有很多浏览器内嵌了此函数)和json2.js。但是,我们的View Model中可能包含observables、computed observables和observable arrays等,这些内容都是作为JavaScript方法进行编译的,此时使用以上的方式并不能完全按照我们的意思把View Model转换为JSON数据。
为了更加方便的将View Model的数据转换为JSON数据,Knockoutjs为我们提供了一些帮助:
(1)、ko.toJS:克隆View Model对象的结构,以当前observable的值代替observable,因此我们仅仅得到了一个View Model的备份,这个备份和Knockoutjs绑定并无关联。
(2)、ko.toJSON:此方法将View Model的数据转换为JSON格式数据,其实现原理就是先通过ko.toJS得到一份View Model的备份,然后通过浏览器本地的JSON序列化函数得到JSON数据。(注:有的浏览器可能没有内置JSON的序列化函数,此时我们可以导入json2.js来进行使用)。
例:定义以下的View Model。
1 <script type="text/javascript"> 2 var viewModel = { 3 firstName: ko.observable("Bert"), 4 lastName: ko.observable("Smith"), 5 pets: ko.observableArray(["Cat", "Dog", "Fish"]), 6 type: "Customer" 7 }; 8 viewModel.hasALotOfPets = ko.computed(function () { 9 return this.pets().length > 2 10 }, viewModel); 11 ko.applyBindings(viewModel); 12 </script>
此View Model中包含了observables、computed observables、observable arrays和plain values,此时我们可以使用ko.toJSON将其转换为JSON数据:
1 var jsonData = ko.toJSON(viewModel); 2 3 // Result: jsonData is now a string equal to the following value 4 // '{"firstName":"Bert","lastName":"Smith","pets":["Cat","Dog","Fish"],"type":"Customer","hasALotOfPets":true}'
或者你仅仅想得到他的备份你可以使用:
1 var plainJs = ko.toJS(viewModel); 2 3 // Result: plainJS is now a plain JavaScript object in which nothing is observable. It's just data. 4 // The object is equivalent to the following: 5 // { 6 // firstName: "Bert", 7 // lastName: "Smith", 8 // pets: ["Cat","Dog","Fish"], 9 // type: "Customer", 10 // hasALotOfPets: true 11 // }
我们的ko.toJSON也可以接受和JSON.stringify同样的参数,此时我们就可以像如下去使用ko.toJSON了:
1 <pre data-bind="text: ko.toJSON($root, null, 2)"></pre>
三、使用JSON数据来更新View Model的数据。
如果我们已经从服务段接受到了数据,并且想要用它来更新我们View Model层的数据,此时最直接的方法就是要我们自己去实现了:
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 5 // Update view model properties 6 viewModel.firstName(parsed.firstName); 7 viewModel.pets(parsed.pets);
在很多的情况下,我们还是要丰衣足食的,当我们更新完View Model的数据之后,Knockoutjs会自动的帮助我们更新UI层的展示。
然而,在很多情况下,很多的开发者可能会使用更为方便的方法来更新View Model层的数据,此时可能只需要编写一行代码对应View Model中的数据就全部更新了,这样就非常的方便,比如我们的View Model有很多的属性,或者嵌套了很多层,我们就可以使用此方式,可以大大减少我们的代码量,具体的方法我们在mapping plugin会具体的介绍。