Knockout允許您實現複雜的客戶端交互性,但幾乎所有Web應用程式還需要與伺服器交換數據,或至少將本地存儲的數據序列化。 最方便的交換或存儲數據的方式是JSON格式 - 大多數Ajax應用程式今天使用的格式。 載入或保存數據 Knockout不強制您使用任何一種特殊技術來載入或保存數據。 您可以... ...
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插件。