knockoutjs複雜對象的可觀察性

問題

對於通常數據結構:html

一、 對於基本類型的數據的變動的可觀察性(observable), 能夠使用  ko.observable(xxx) 來聲明一個 observable對象,git

  或將其綁定到視圖,github

  或將其綁定到其它 ko.computed 或者 ko.pureComputed 對象中;json

  或者使用subscribe單獨訂閱其變化。數組

二、 對於數組型號數據結構, ko提供 ko.observableArray(xxx), 將數組作成一個可觀察對象, 並開放一些相似數組的 方法,restful

  使用這些方法, 一旦數組發生變化, 則觀察者可以被通知到。數據結構

pop, push, shift, unshift, reverse, sort, splice

All of these functions are equivalent to running the native JavaScript array functions on the underlying array, and then notifying listeners about the change:app

  • push( value ) — Adds a new item to the end of array.
  • pop() — Removes the last value from the array and returns it.
  • unshift( value ) — Inserts a new item at the beginning of the array.
  • shift() — Removes the first value from the array and returns it.
  • reverse() — Reverses the order of the array and returns the observableArray (not the underlying array).
  • sort() — Sorts the array contents and returns the observableArray. The default sort is alphabetical, but you can optionally pass a function to control how the array should be sorted. See the example under sorted below.
  • splice() — Removes and returns a given number of elements starting from a given index. For example, myObservableArray.splice(1, 3) removes three elements starting from index position 1 (i.e., the 2nd, 3rd, and 4th elements) and returns them as an array.

replace, remove and removeAll

observableArray adds some more useful methods that aren’t found on JavaScript arrays by default:less

  • replace( oldItem, newItem ) — Replaces the first value that equals oldItem with newItem.
  • remove( someItem ) — Removes all values that equal someItem and returns them as an array.
  • remove( function (item) { return item.age < 18; } ) — Removes all values whose age property is less than 18, and returns them as an array.
  • removeAll( ['Chad', 132, undefined] ) — Removes all values that equal 'Chad', 123, or undefined and returns them as an array.
  • removeAll() — Removes all values and returns them as an array.

 

問題來了, 咱們的常用的 json數據結構, 相似restful等接口提供的數據, 如何觀測其變化, 並通知到觀察者?ui

 

KO.MAPPING

https://knockoutjs.com/documentation/plugins-mapping.html

使用ko,mapping插件, 能夠將json對象, 轉換一個嵌套的元素級別的可觀察對象。

例如:

-------------------------------------

[

    1, 2, 3

]

這個跟 ko.observableArray功能一致。

------------------------------------

[

{

  "a": 1

}

]

除了最外層的數組,被轉換爲 ko.observableArray外, 內部嵌套 "a"的屬性值,也被轉換爲一個 ko.observable對象。

Example: Using ko.mapping

To create a view model via the mapping plugin, replace the creation of viewModel in the code above with the ko.mapping.fromJS function:

var viewModel = ko.mapping.fromJS(data);

This automatically creates observable properties for each of the properties on data. Then, every time you receive new data from the server, you can update all the properties on viewModel in one step by calling the ko.mapping.fromJS function again:

// Every time data is received from the server:
ko.mapping.fromJS(data, viewModel);

 

可是整個 {} 自己是沒有被轉換爲 ko.observable 對象。

下面給給出一個簡單方法

 

對整個{}對象觀察

ko.observable

https://knockoutjs.com/documentation/observables.html

 

var json = {"a": 1}

var obser = ko.observable(json);

var kobser = ko.computed(function(){

  return obser()["a"] + 1;

})

 

// 這樣一改變後, kobser也會跟着變化。

obser({"a": 2})

Writable computed observables

https://knockoutjs.com/documentation/computed-writable.html

爲json對象定義到一個 ko.computed對象, 使用read方法負責讀, 使用write負責寫。 本質上與ko.observable方法相同,有特殊邏輯處理的時候, 才用這個方法。

function MyViewModel() {
     this .firstName = ko.observable( 'Planet' );
     this .lastName = ko.observable( 'Earth' );
 
     this .fullName = ko.pureComputed({
         read: function () {
             return this .firstName() + " " + this .lastName();
         },
         write: function (value) {
             var lastSpacePos = value.lastIndexOf( " " );
             if (lastSpacePos > 0) { // Ignore values with no space character
                 this .firstName(value.substring(0, lastSpacePos)); // Update "firstName"
                 this .lastName(value.substring(lastSpacePos + 1)); // Update "lastName"
             }
         },
         owner: this
     });
}
 
ko.applyBindings( new MyViewModel());

knockout-store

https://github.com/Spreetail/knockout-store

相關文章
相關標籤/搜索