Objective
Knockout is designed to allow you to use any JavaScript object as the view model. Some properties of the view model must be observable, and you can use KO to bind them to your UI elements, which are automatically updated when these observable values change.
Use mapping to reference the JS file https://github.com/SteveSanderson/knockout.mapping/tree/master/build/output.
Handmade mapping
Displays the current server time and the current number of users on your site. You should use the following view model to represent this information:
var ViewModel = { serverTime:ko.observable (), numUsers:ko.observable () };
Then bind the view model to the HTML element, as follows:
is: <span data-bind="text:servertime" ></span> and<span data-bind="text: Numusers"></span> user (s) is connected.
Because the view model property is observable, when they change, KO automatically updates the bound HTML element.
Next, get the latest data from the server. Perhaps every 5 seconds you want to invoke an AJAX request (for example, using jquery's $.getjson or $.ajax correspondence):
gets the server-side data function GetData () { $.getjson (".. /home/getserverdata? token="+new Date (), {}, function (data) {viewmodel.servertime (data). Date); Viewmodel.numusers (data. Count); }); SetInterval ("GetData);} GetData ();
Background call method returns JSON data
Public Jsonresult Getserverdata () { serverdata sd=new serverdata (); Sd. Date = DateTime.Now.ToString ("yyyy-mm-dd hh:mm:ss"3this. Json (SD, Jsonrequestbehavior.allowget); }
and defines a simple entity class.
Class Serverdata { setset;}}
The returned data is displayed as
Finally, using this data to update your view model (without using the mapping plugin), the code is
Viewmodel.servertime (data. Date); Viewmodel.numusers (data. Count);
The final page is bound with the data by KO Automatic Update
To make the data appear on the page, all of the properties are written like this. If your data structure is complex (for example, containing sub-objects or arrays), it is quite painful to maintain them. The mapping plugin is for converting your JavaScript Simple object (or JSON structure) into the observable view model.
Using ko.mapping
Create a view model from the mapping plugin and use the Ko.mapping.fromJS function directly to create:
var ViewModel = Ko.mapping.fromJS (data);
It automatically creates attributes of the observable type into all the attributes in data. You can periodically fetch data from the server via the Ko.mapping.fromJS function and then update your view model:
Ko.mapping.fromJS (data,{}, ViewModel);
How to Mapping
All properties of the object are converted to the observable type value, and if the value of the obtained object changes, the value of the observable type is updated.
Arrays are also converted to observable arrays, and if the server update changes the number of arrays, the mapping plugin will also add or delete the corresponding item items, and will try to maintain the same order sequence as the native JavaScript array.
Unmapping
If you want to convert a map object to the original JavaScript object, use the following:
var unmapped = Ko.mapping.toJS (ViewModel);
The two field names of the previously created entity class objects are modified to match the names of the properties in the view model.
Creates a Unmapped object that contains only the properties of the object you previously map, in other words, the properties or functions you add manually on the view model are ignored, except that the _destroy property can be unmapped back because you This property is generated when the Ko.observablearray destroy an item item. Please refer to the "Advanced Usage" section to configure usage.
Working with JSON strings
If your Ajax call returns a JSON string (rather than a deserialized JavaScript object), you can use the Ko.mapping.fromJSON function to create or update your view model. Implement Unmap with Ko.mapping.toJSON.
Using the. From/tojson function to handle JSON strings and using the. from/tojs function to handle JS objects is equivalent.
Knockout.js Official website Study (mapping advanced usage one)
Objective
Sometimes, when using Ko.mapping.fromJS, it may be necessary to use the advanced usage of mapping to define the detailed process of the mapping, which is defined later and is no longer defined when it is called later. Here are some scenarios where you may need to use these option.
Use keys to make objects unique
You have a JavaScript object, as follows:
'Scot'ALICW'}];
And he's bound to ViewModel.
var ViewModel = { name:ko.observable ("Scot"'alicw' }])};
With the map plugin, you can map it to the view model (no problem):
'Scott'alicws'} ]; Ko.mapping.fromJS (Data,{},viewmodel);
Two things happened here: name changed from Scot to Scott,children[0].name from ALICW to ALICWS. By debugging you can find that the properties in the ViewModel have changed accordingly in the update.
So, name is updated as we expected, but in the children array, the subkey ALICW is deleted and the new item Alicws is added to the array. This is not what we expect, we expect to just update the name from ALICW to ALICWS, instead of replacing the entire item item. This occurs because, by default, the mapping plugin plug-in simply compares the two objects in the array to be equal. Because JavaScript {id:1, name: ' ALICW '} and {id:1, Name: ' Alicws '} are not equal, it feels like replacing the old item with the new item.
To solve this problem, you need to declare a key to let the mapping plugin use to determine whether an object is a new object or an old object. The code is as follows:
var mapping = { 'children'return ko.utils.unwrapObservable (data.id); }};
Ko.mapping.fromJS (data, mapping, ViewModel);
Thus, each time the map is mapping, the plugin checks the id attribute of the array item to determine whether the array item needs to be merged or new replace.
Constructor for custom object with Create
If you want to control mapping yourself, you can also use the create callback. Using callbacks allows you to control mapping yourself.
For example, you have a JavaScript object like this:
'Graham'Lisa'};
If you want to map the children array yourself, you can declare this:
var Mychildmodel = function (data) {This ); }; 'childrenNew Mychildmodel (options.data); }};
Ko.mapping.fromJS (data, mapping, ViewModel);
The options parameter that supports the create callback is a JavaScript object that contains the following:
Data:javascript object that contains the data used by the child
The parent object or array to which the Parent:child object belongs
If you want the initial JavaScript object to have additional dependency properties dependent observables:
var Mychildmodel = function (data) {This ); This );};
Updating of custom objects with update
You can also use the update callback to customize how an object is updated. It accepts an object that needs to be replaced and the same options parameter as the create callback, and you should return the updated value.
The options parameter used by the update callback is a JavaScript object that contains the following:
Data:javascript object that contains the data used by the child
The parent object or array to which the Parent:child object belongs
Observable: If the property is observable, this will be written to the actual observable
example, append additional strings after the new data before the data is displayed:
'Graham' }; 'name'foo!' var ViewModel = Ko.mapping.fromJS (data, mapping); alert (Viewmodel.name ());
Then the result of alert is
Knockout.js Official website Study (mapping Advanced Usage II)
Use Ignore to ignore properties that do not require a map
If you want to ignore some properties when you're at map, you can use Ignore to declare a collection of property names that you want to ignore:
var data = { name< Span style= "color: #800000;" > ": " aehyok "age": "25 "}; var mapping = { ignore< Span style= "color: #800000;" > ': [ ' age ' ] }; var ViewModel = Ko.mapping.fromJS (data, mapping);
After this execution, age does not viewmodel in the
The ignored array you declared is compiled into the default ignore array. You can maintain it just like the following code:
var oldoptions = ko.mapping.defaultOptions (). Ignore; Ko.mapping.defaultOptions (). Ignore = ["alwaysignorethis"];
Use the include declaration to require map properties
By default, when you map your view model back to the JS object it is time to map only the attributes owned by the original view model (except for the exception of the _destroy attribute), but you can use the include parameter to customize:
var mapping = { 'include': ["propertytoinclude"alsoincludethis"]};
var ViewModel = Ko.mapping.fromJS (data, mapping);
The include array you declare is compiled into the default include array, which is only _destroy by default. You can maintain it like this:
var oldoptions = Ko.mapping.defaultOptions (). Include;
Ko.mapping.defaultOptions (). include = ["alwaysincludethis"];
Copy properties using copy
By default, map is the time to convert all values to observable, and if you just want to copy the property value instead of replacing it with observable, you can add the property name to the copy array:
var mapping = { 'copy': ["propertytocopy"]};
var ViewModel = Ko.mapping.fromJS (data, mapping);
The copy array you declared is compiled into the default copy array, and the default value is null. You can maintain it like this.
var oldoptions = ko.mapping.defaultOptions (). copy;
Ko.mapping.defaultOptions (). copy = ["alwayscopythis"];
Specifying the update target
In the example above, if you want another class map, you can use the third parameter as the target of the operation, for example:
So, if you want to map a JavaScript object to this, you can declare this:
this);
From the data source map
You can map the data sources of multiple JS objects together by using Ko.mapping.fromJS multiple times, for example:
var ViewModel = Ko.mapping.fromJS (Alice, Alicemappingoptions);
Ko.mapping.fromJS (Bob, Bobmappingoptions, ViewModel);
The observable array after map
Map plugin map produces a observable array, with several additional functions to handle the mapping with keys:
Mappedremovemappedremoveallmappeddestroymappeddestroyallmappedindexof
They are equivalent to the functions in the Ko.observablearray, but they work with the object by key. For example:
2 }]; return2});
Map over the observable array, in addition to the above function also supports a mappedcreate function:
3});
First checks if key (id=3) exists in the array (throws an exception if it exists), then calls them if there are create and update callbacks, creates a new object, adds the new object to the array, and returns the new object.
7.knockout.js (mapping plug-in)