Knockoutjs 3.X API Eighth Map (mapping) Plugin

Source: Internet
Author: User
Tags javascript array

Knockout is designed to allow you to use any JavaScript object as a view model. As long as the properties of some view models are observables, you can use KO to bind them to your UI, and the UI will automatically update when observable properties change.

Most applications need to get data from back-end servers. Because the server does not have any observable concept, it only provides a pure JavaScript object (usually serialized as JSON). The mapping plug-in provides an easy way to map this simple JavaScript object to a view model with the appropriate observables. This is an alternative to manually writing your own JavaScript code to build a view model based on some of the data you get from the server.

Download the mapping plugin (you need to flip a wall)
    • Version 2.0 (8.6kb minified),

<BR class= "Apple-interchange-newline" ><div id= "Inner-editor" ></div>

Example: manual mapping without a ko.mapping plugin

You want to display the current server time and the number of users on your page. You can use the following view models to represent this information:

var viewModel = {    serverTime:ko.observable (),    numUsers:ko.observable ()}

You can bind this view model to some HTML elements, as follows:

<data-bindservertime '></span>  <data-bindnumusers ' ></  Span> User (s) is connected.

Because the view model properties are observable, KO will automatically update the HTML elements when these properties change.

Next, you want to get the latest data from the server. Every 5 seconds you can make an AJAX request (for example, a $. Getjson or $. ajax function using jquery):

var data = Getdatausingajax ();          // Gets The data from the server

The server may return JSON data similar to the following:

{    ' 2010-01-07 ',    3}

Finally, to update the view model with this data (without using the mapping plug-in), you should write:

// every time data is received from the server: Viewmodel.servertime (data.servertime); viewmodel.numusers (data.numusers);

You must do this for each variable that you want to display on the page. If your data structure becomes more complex (for example, they contain child nodes or contain arrays), manual processing becomes cumbersome. The mapping plugin allows you to create a mapping from a regular JavaScript object (or JSON structure) to the observable view model.

<BR class= "Apple-interchange-newline" ><div id= "Inner-editor" ></div>

Example: Using ko.mapping

To create a view model from a mapping plug-in, replace the creation of ViewModel in the above code with the Ko.mapping.fromJS function:

// every time data is received from the server:Ko.mapping.fromJS (data, ViewModel);
How to map
    • All properties of the object are converted to observable. If the update will change the value, it will update observable.
    • The array is converted to an observable array. If the update changes the number of items, it will perform the appropriate Add/remove operation. It will also try to maintain the same order as the original JavaScript array.

If you want to convert a mapped object back to a regular JS object, use:

var unmapped = Ko.mapping.toJS (ViewModel);

This creates an Unmapped object that contains only the properties of the mapped object as part of the original JS object. Therefore, in other words, any properties or functions that you manually add to the view model are ignored. By default, the only exception to this rule is the _destroy property, which is also mapped back because it is a knockout property that may be generated when the project is destroyed from Ko.observablearray. For more details on how to configure this item, see the "Advanced Apps" section.

Using JSON strings

If your Ajax call returns a JSON string (and does not deserialize it into a JavaScript object), you can use the function Ko.mapping.fromJSON to create and update the view model. To cancel the mapping, you can use Ko.mapping.toJSON.

In addition to the fact that they use JSON strings instead of JS objects, these functions are exactly the same as their JS objects.

Advanced usage

Sometimes it may be necessary to have more control over how mappings are performed. This is achieved using the mapping option. They can be specified during the Ko.mapping.fromJS call. In subsequent calls, you do not need to specify them again.

In this case, you may need to use these mapping options.

Use "key" to uniquely identify an object

Suppose you have a JavaScript object that resembles the following:

var data = {    ' Scot ',    children: [        1, Name: ' ALICW ' }    ]}

You can map this to the view model without any problems:

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

Now, suppose the data is updated to have no spelling errors:

var data = {    ' Scott ',    children: [        1, Name: ' Alice ' }    ]}

Two things happen here: name changed from Scot to Scott,children[0]. Name changed from ALICW to Alice. You can update viewmodel based on this new data:

Ko.mapping.fromJS (data, ViewModel);

And the name will change as expected. However, in the children Array, the child (ALICW) is completely removed and a new (Alice) is added. This is not exactly what you would expect. Instead, you will want only the child's name attribute to be updated from ALICW to Alice, instead of the entire child being replaced!

This is because, by default, the mapping plug-in simply compares the two objects in the array. Because in JavaScript, the object {id:1,name: ' ALICW '} is not equal to {id:1,name: ' Alice '}, it thinks the entire child needs to be deleted and replaced by a new one.

To solve this problem, you can specify which key the mapping plug-in should use to determine whether the object is new or old. You can set this:

var mapping = {    ' children ': {        function(data) {            return  ko.utils.unwrapObservable (;     }}} var viewModel = Ko.mapping.fromJS (data, mapping);

This way, each time the mapping plug-in examines an item in the children array, it only looks at the ID property to determine whether an object is completely replaced or just needs to be updated.

Customizing object construction with "create"

You can also provide a create callback if you want to handle part of the mapping yourself. If this callback is present, the mapping plugin will allow you to do this part of the mapping yourself.

Suppose you have a JavaScript object that resembles the following:

var data = {    ' Graham ',    children: [        1, Name: ' Lisa ' }    ]}

If you want to map the children array yourself, you can specify this:

var mapping = {    ' children ': {        function(options) {              Returnnew  Mychildmodel (;     }} var viewModel = Ko.mapping.fromJS (data, mapping);

The options parameter provided to the create callback is a JavaScript object that contains:

    • data: A JavaScript object that contains data for this subkey
    • parent: Parent object or array to which this subkey belongs

Of course, in the create callback you can do another call to Ko.mapping.fromJS if you want. A typical use case might be if you want to augment the original JavaScript object with some extra computational observables:

var function (data) {    this);          this. Namelength = ko.computed (function() {        returnthis. Name (). length;      This );}
Customizing object updates with "Update"

You can also customize how objects are updated by specifying update callbacks. It will receive the object it is trying to update and one of the same options used by the create callback. You should return the updated value.

The options parameter that is provided to the update callback is a JavaScript object that contains: * Data: A JavaScript object containing data for this child node * Parent: This child node belongs to an object or array * Observable: If the property is observable will be set to the actual observable

Here is a sample configuration that will add some text to the input data before the update:

var data = {    ' Graham 'var mapping = {    ' name ': {          function(options) {            return + ' foo! ' ;        }    }} var viewModel = Ko.mapping.fromJS (data, mapping); alert ( ());

This will pop the window tip Graham Foo!

Ignore some properties using "ignore"

If you want to map a plugin to ignore some of the properties of your JS object (that is, do not map them), you can specify an array of property names to ignore:

var mapping = {    ' ignore ': ["Propertytoignore", "Alsoignorethis"]}var ViewModel = Ko.mapping.fromJS (data, mapping);

The Ignore array that you specify in the mapping option is combined with the default ignored array. You can manipulate this default array like this:

var oldoptions == ["Alwaysignorethis"];
Include some properties with "include"

When you convert a view model back to a JS object, by default, the mapping plug-in will only contain properties that belong to the original view model, but it will also include the _destroy property generated by the knockout, even if it is not part of the original object. However, you can choose to customize this array:

var mapping = {    ' include ': ["Propertytoinclude", "Alsoincludethis"]}var ViewModel = Ko.mapping.fromJS (data, mapping);

The include array that you specify in the mapping option is combined with the default include array, which by default contains only _destroy. You can manipulate this default array like this:

var oldoptions == ["Alwaysincludethis"];
To copy certain properties using "copy"

When you convert a view model back to a JS object, by default, the mapping plug-in creates an observable based on the rules described above. If you want to force the mapping plug-in to simply copy the property instead of making it visible, add its name to the "copy" array:

var mapping = {    ' copy ': ["Propertytocopy"]}var viewModel = Ko.mapping.fromJS ( data, mapping);

The replica array that you specify in the mapping option is combined with the default copy array, which is empty by default. You can manipulate this default array like this:

var oldoptions == ["Alwayscopythis"];
Use only "observe" to observe certain properties

If you want the map plugin to only create some properties of your JS object that can be observed and copied, you can specify an array of attribute names to observe:

var mapping = {    ' observe ': ["Propertytoobserve"]}var viewModel = Ko.mapping.fromJS (data, mapping);

The observation array that you specify in the mapping options is combined with the default observation array, which is empty by default. You can manipulate this default array like this:

var oldoptions == ["Onlyobservethis"];

The array is ignored and includes still working correctly. An array copy can be used to replicate the efficiency of an array or object property, including child elements. If you do not specify an array or an object property in copy or observe, it will be recursively mapped:

var data = {    "a",    "v1"}, {b2: "v2"var result = Ko.mapping.fromJS ( Data, {observe: "a" }); var // 'll is faster to map.

Results and Results 2 will be:

{    a:observable ("a"),    "v1"}, {b2: "v2" }]}

Replication and observation can conflict:

var data = {    "a",    "v1"}, {b2: "v2" }]}; var result = Ko.mapping.fromJS (data, {observe: "B[0].B1"}); var result2 = Ko.mapping.fromJS (data, {observe: "B[0].b1", copy: "B"});

The result will be:

{    "a",    B: [{b1:observable ("v1")}, {b2: "v2" }]}

The result 2 will be:

{    "a",    "v1"}, {b2: "v2" }]}
Specify update targets

If, as in the example above, you are performing a mapping in a class, you want to have it as the target of your mapping operation. The third parameter of the Ko.mapping.fromJS indicates the target. For example

// overwrites properties on Someobject

So, if you want to map a JavaScript object here, you can pass this as a third parameter:

Mapping from multiple sources

You can combine multiple JS objects in a single view model by applying multiple Ko.mapping.fromJS calls, for example:

var viewModel = Ko.mapping.fromJS (Alice, Alicemappingoptions); Ko.mapping.fromJS (Bob, Bobmappingoptions , ViewModel);

The mapping options that are specified in each call are merged.

Array of mapping monitoring properties

The observable array generated by the mapping plug-in is augmented by a number of functions that can be used to map keys:

    • Mappedremove
    • Mappedremoveall
    • Mappeddestroy
    • Mappeddestroyall
    • Mappedindexof

They are functionally equivalent to regular ko.observablearray functions, but can do things based on the key of the object. For example:

var obj = [    1 },    2var result = Ko.mapping.fromJS (obj, {    /c7>function(item) {        return  ko.utils.unwrapObservable (;     2});

The mapped Observablearray also exposes a mapped create function:

var newitem = Result.mappedcreate ({id:3});

It will first check if the key is already present and, if so, throws an exception. Next, it will invoke the Create and update callbacks (if any) for creating a new object. Finally, it adds the object to the array and returns it.

Knockoutjs 3.X Conclusion

At this point, all Knockoutjs 3.X API documentation has been written, I hope this complete Knockoutjs Chinese document can help you, thank you for reading. If you feel good, please point a wave of recommendations, attention. If you feel that there is something wrong in the text, please criticize it.

Thank you for reading.

Reprint Please specify source:

Thanks again

Knockoutjs 3.X API Eighth Map (mapping) Plugin

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.