Giter VIP home page Giter VIP logo

knockout.mapping's People

Contributors

andersmalmgren avatar barkmadley avatar bryansquared avatar busticated avatar cspotcode avatar domenic avatar dzenisevichk avatar gplwhite avatar jamesfoster avatar jpc avatar klaster1 avatar lawnsea avatar rho24 avatar sagacity avatar stevesanderson avatar supergibbs avatar tavriets avatar timtucker avatar vantreeseba avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

knockout.mapping's Issues

"item.evaluate is not a function" when using create as in docs

Hi,

i have a mapping for fromJs with create like in the docs section "Customizing object construction using “create”" in http://knockoutjs.com/documentation/plugins.mapping.html
So i'm extending the data with dependentObservables and subscriptions.

The line 126 in knockout.mapping.debug.js gives me an error as stated in the title.
The error is reproducable with the sample from the metioned docs section.

For now i can work and test with the line commented. Will this have any side effects?

VisitedObjects is not being cleared at end of toJSON or toJS

The temp object visitedObjects is being left on the mapping object, which causes stale data to be used in subsequent calls to both toJSON and toJS. It should really be deleted at the end of the call so the next call walks the view model again rather than using data from the prior call. The parentName should also be removed at that time.

From a design point of view it would be better if the argument was not modified at all, but passed separately within the methods.

I will provide a test case when I get a minute.

toJS unmaps all properties of sub-objects

fromJS keeps a log of all properties that are mapped. toJS only unmaps properties that were tracked. But this seems to hold true only for the first level of properties in a tree of objects.

Example: see also http://jsfiddle.net/U4nDp/

var person = ko.mapping.fromJS({
firstname: "Knock",
lastname: "McOut",
address: {
street: "Some Street",
number: "123"
}
}),
personJS;

person.fullName = ko.computed(function() {
return person.firstname + ' ' + person.lastname;
});
person.address.fullStreet = ko.computed(function() {
return person.address.number + ' ' + person.address.street;
});

personJS = ko.mapping.toJS(person);

personJS does NOT contain fullName (which is correct), but DOES contain person.address.fullStreet.

I'd expect that fullStreet is not unmapped by toJS either. Stepping through the fromJS implementation I can also watch the individual properties of address being added to the mappedProperties, but they seem to be ignored in the toJS implementation.

ko.mapping.ToJSON () question

Hi Roy, i have a new behavior with the latest mapping plugin. I've made this fiddle example http://jsfiddle.net/pierol/RtJaH/1/ example that reproduce the problem. I create a viewmodel with a ko.mapping.fromJS(data1), where data1 is a JSON object obtain from a AJAX call. In this object there is a void Immagini array that become an observable array when i call the fromJS function. Then i add to this array an element with the viewModel.Immagini.push(newelement) when i press the add button, but when i made the ko.mapping.toJSON(viewmodel), in the Immagini array there is a void element: {}. Is that an expected behavior of the plugin or this is an issue ?

AMD/RequireJS support

The lastest branch of Knockout supports AMD/RequireJs. While converting your code to also use AMD/RequireJS ran into some issues. The knockout.mapping has the following function in it:

ko.exportSymbol = function (publicPath, object) {
var tokens = publicPath.split(".");
var target = window;
for (var i = 0; i < tokens.length - 1; i++)
target = target[tokens[i]];
target[tokens[tokens.length - 1]] = object;
};

and it uses the var target = window as the start. knockout.js has a
similar function, but it uses target = ko as the start.

I'd like to ask for that change, and
that way the ko.exportSymbol() usage at the bottom of the file can be
reduced. It is unclear though that any of that export symbol stuff is
needed at all in the mapping file since it starts at the top of the
file and does a ko.mapping = {} anyway.

Array mapping error

Hi, I have following code that is incorrect mapped:

var obj = {}, obj2 = {};
var x = [obj,obj2];
var y = { o: obj, x: x };

var z = ko.mapping.fromJS(y);

Unfortunately z.x()[0] is undefined. I notice that that happend because of the following calling updateViewModel with undefined mappedRootObject.

485: mappedItem = ko.utils.unwrapObservable(updateViewModel(undefined, item, options, parentName, mappedRootObject, fullPropertyName));

Then in update viewModel is the following line that returns that undefined:

303: if (visitedObjects.get(rootObject)) return mappedRootObject;

the ko.mapping.toJS(viewmodel) memory leak

My view model is this:

 viewModel = {
        init: function () {
            $.ajax({
                type: 'GET',
                url: 'adminprodotto/init',
                async: false,
                contentType: 'application/json; charset=utf-8',
                success: function (data) {
                    $.extend(viewModel, ko.mapping.fromJS(data));
                    /*ko.utils.unwrapObservable(viewModel.Immagini);*/
                },
                error: function () {

                }
            });
        },
        vuoto: function () {
            $.ajax({
                type: 'GET',
                url: 'adminprodotto/init',
                async: false,
                contentType: 'application/json; charset=utf-8',
                success: function (data) {
                    ko.mapping.fromJS(data, viewModel)
                },
                error: function () {

                }
            });
        },
        save: function () {
            //alert(ko.mapping.toJSON(viewModel.Allegati));
            $.ajax({
                type: 'POST',
                url: 'adminprodotto/update',
                contentType: 'application/json; charset=utf-8',
                data: JSON.stringify(ko.mapping.toJS(viewModel)),
                success: function (data) {
                    $('#modal-prodotto').modal('hide');
                    tabellaProdotti.fnStandingRedraw();

                },
                error: function (jqXHR, textStatus, errorThrown) { alert('Errore:' + errorThrown) }
            });
        },
        edit: function (key) {
            $.ajax({
                type: 'GET',
                async: false,
                url: 'adminprodotto/detail?IdProdotto=' + key,
                contentType: 'application/json; charset=utf-8',
                success: function (data) {
                    ko.mapping.fromJS(data, viewModel);
                    $('#modal-prodotto').modal('show');
                },
                error: function (jqXHR, textStatus, errorThrown) { alert('Errore:' + errorThrown) }
            });
        },
        erase: function () {
            $.ajax({
                type: 'POST',
                url: 'adminprodotto/delete',
                async: false,
                data: JSON.stringify({ IdProdotto: viewModel.Prodotto.IdProdotto() }),
                contentType: 'application/json; charset=utf-8',
                success: function (data) {
                    $("#modal-delete-prodotto").modal('hide');
                    tabellaProdotti.fnStandingRedraw();
                },
                error: function (jqXHR, textStatus, errorThrown) { alert('Errore:' + errorThrown) }
            });
        },
        annulla: function () {
            tabellaProdotti.fnStandingRedraw();
        },
        removeImmagine: function (immagine, data) {
            immagine = ko.mapping.toJS(immagine);
            $.ajax({
                type: 'POST',
                url: '/file/deletefileimmagine',
                async: false,
                data: JSON.stringify({ Url: immagine.Url, IdProdottoImmagine: immagine.IdProdottoImmagine }),
                contentType: 'application/json; charset=utf-8',
                success: function (data) {
                    if (data == "ok") {
                        viewModel.Immagini.remove(function (item) {
                            return (item.IdProdottoImmagine() == allegato.IdProdottoImmaginr)
                        });
                    }
                },
                error: function (jqXHR, textStatus, errorThrown) { alert('Errore:' + errorThrown) }
            });
            return true; 
        },
        removeAllegato: function (allegato, data) {
            allegato = ko.mapping.toJS(allegato);
            $.ajax({
                type: 'POST',
                url: '/file/deletefileallegato',
                async: false,
                data: JSON.stringify({ Url: allegato.Url, IdProdottoAllegato: allegato.IdProdottoAllegato }),
                contentType: 'application/json; charset=utf-8',
                success: function (data) {
                    if (data == "ok") {
                        viewModel.Allegati.remove(function (item) {
                            return (item.IdProdottoAllegato() == allegato.IdProdottoAllegato)
                        });
                    }
                },
                error: function (jqXHR, textStatus, errorThrown) { alert('Errore:' + errorThrown) }
            });
            return true;
        }

    }

after five o six call to the "save" method of the viewmodel the call toJSON (i've tried with toJS same issue) cause a memory leak. I've tried the latest version of the plugin (debug version) and knockout (in chrome says thant the page is crashed, in firefox that a script doesn't respond anymore).

Documentation Bug: array → copy

From the KO website:

Copying certain properties using “copy”

When converting your view model back to a JS object, by default the mapping plugin will create observables based on the rules explained above. If you want to force the mapping plugin to simply copy the property instead of making it observable, add its name to the “copy” array:

var mapping = {
    'array': ["propertyToCopy"]
}
var viewModel = ko.mapping.fromJS(data, mapping);

Fairly sure that 'array' should be 'copy'.

Latest Build Broken? Or Installation Issue?

With your console open, check out: http://jsfiddle.net/3t4yA/1/

I'm getting an error ("Result of expression 'ko.a.c' [undefined] is not a function.") with what appears to be a pretty well-bounded test case taken directly from the documentation.

Is there another simple way to confirm the plugin is installed properly?

Dependent observable proxy doesn't work with read/write syntax

From https://groups.google.com/forum/#!topic/knockoutjs/TwtEpeOzmi8:

I have found another issue with the mapping plugin not deferring execution of dependentObservable's, which is related to my earlier post.

The new case arises when using a a r/w object is passed to the dependentObservable() vs. using the single parameter syntax.

ex. ko.dependentObservable( { read: textinput_dependentObservable, write: textinput_rw_dependentObservable, owner: this.artext() } );

executes immediately instead of being deferred until ko.mapping.fromJS() completes.

@barkmadley, if/when you have time could you update your patch to address this - many thanks.

toJSON method clings to the first "" or false found while parsing

http://stackoverflow.com/questions/6858145/knockout-mapping-fromjs-of-arrays-containing-false-replaces-empty-strings/

Seems like the toJSON method clings to the first ""(empty string) or false found in the object and places this found value through out the rest of the object where ever it finds either a "" or a false.

A better visual of this can be seen here http://jsfiddle.net/5HhMn/

In the example try changing the first "" to a false and see it propagate to the other values.

Differenciate between create/update and createItem/updateItem

All in all I would prefer if create/update would not behave different for arrays than for normal scalars:

create: receives the entire source data/array as options.data
update: receives the target data/array as target and the source data/array as options.data

Since most use cases will probably want to perform a simple create/update per item, two extra methods could be introduced:

createItem: behaves the same as the current create function for arrays
updateItem: behaves the same as the current update function for arrays

When overwriting the normal update/create methods for arrays one must take care to implement the key logic, but it the end it would make it possible to perform extremely powerful mappings.

Example:

source: {"foo": {...fooProps...}, "bar": {...barProps...}}
target: [{"name": "foo", ...fooProps...}, {"name": "bar", ...barProps...}]

In an application I'm currently writing I wanted to do exactly this but had to change the server return value to the target array because I was not able to map objects to array properties of the target model. With the proposed change such mappings are possible and the API becomes much more logical.

Options notation

Options format:

How can I use objects with copy, include, ignore properties in fromJS/toJS calls?

This is not possible with current options notation or I'm wrong?

Options format is: {
  copy|include|ignore: <paths to properties>,
  <paths to properties>: {
    key|create|update: <callbacks>
  }
}

To fix this we need to change format to: {
  <paths to properties>: copy|include|ignore,
  <paths to properties>: {
    key|create|update: <callbacks>
  }
}

or as variant of this - replace <paths to properties> with real object structure...

Currently <paths to properties> may be only single property name for key, create, update callback. This example will fail: {
  "a.b": {
    key|create|update: <callbacks>
  }
}

This was not fixed by #63 issue because related to indexes of arrays.

Options updating:

it's also not clear topic of options merging/updating for nested mapping.
We cannot use options for root in nested mapping in create/update because this will introduce dependencies between structures of objects.

As a solution for this I may suggest to use callback or <nested options definition> with create.

Options and arrays:

Currently all arrays are processed with compareArrays function which also sorts arrays. And how is it possible to use indexes of items in <paths to properties>?

Calling ko.mapping.fromJS() inside a ko.computed cause endless loop

Here is the source code:

if (!ui.loadSubscriptions) ui.loadSubscriptions = ko.computed(function() {
    var client = data.curClient();
    if (!client.subscriptions) {
        $.ajax({
            url: '/data/client/subscriptions',
            dataType: 'json',
            async: false,
            data: {id: client._id()},
            success: function(subscriptions) {
                // ! the following statement cause the entire function been
                // evaluate again and the ajax call will be executed again
                // and so forth the mapping call. It generates an endless
                // loop
                client.subscriptions = ko.mapping.fromJS(subscriptions);
            },
            error: function(jqXHR, textStatus, errorThrown) {
                _.error("error load client subscriptions");
                throw errorThrown;
            }
        });
    }
});

Have doubts, but...

Hi!

Doesn't it make sence to check before line 371 (// For non-atomic types, visit all properties and update recursively //) if the property alreday has been mapped by updateCallback (line 365)? And if so , not map these properties, since it is supposed that they already have been mapped by custom update?

The solution - add line 371

if (!hasUpdateCallback()) {

ko.mapping.toJSON ignores options parameter

I guess

ko.mapping.toJSON = function (rootObject, options) {
  var plainJavaScriptObject = ko.mapping.toJS(rootObject);
  return ko.utils.stringifyJson(plainJavaScriptObject, options);
};

should be

ko.mapping.toJSON = function (rootObject, options) {
  var plainJavaScriptObject = ko.mapping.toJS(rootObject, options);
  return ko.utils.stringifyJson(plainJavaScriptObject);
};

Attach a single Js Object back to a mapped parent causes browser crash

I'm creating a list of items which are mapped using the mapping plugin. However, I want to be able to 'attach' or copy a single object back to the mapped object inside an observableArray. Effectively, it is used where there is a list of items, and an edit dialog is shown for the item. When clicking 'ok' the data should map back to the source.

I have a very simple jsFiddle, but this is crashing the browser:
http://jsfiddle.net/5J9aL/8

I thought maybe using the mapping options to map the actual object inside the array might fix the problem, but no luck:
http://jsfiddle.net/RJqdD/1

On further inspection: extendObject seems to be getting into a recursive endless loop. Can anyone check this for me to see if there is a resolution?

ko.mapping.fromJS(data, self) doesn't work after reset

After the form is reset reloading the data back from server by calling ko.mapping.fromJS(data, self) where self is the viewModel and data is the new json, will do the same as pressing reset again instead of loading updated data from server.

Any advices?

Mapping arrays with duplicate values mangles the array

var foo = ["1", "1", "1", "2", "3", "1", "2"];
var bar = ko.mapping.fromJS(foo);
console.log( ko.mapping.toJS(bar) ); // ["1", undefined, undefined, "2", "3"]

As you can see in the example, the first series of duplicate items in the array become undefined, and any subsequent duplicate values completely disappear. This occurs whether mapping.toJS or when binding to elements in the DOM.

Tested with knockout 1.2.1 and mapping 1.0.

subscribing to a computed when mapping

Hi I've set up a simple demo of the issue I'm having

http://jsfiddle.net/x3PLB/

I'm not sure if it requires a doubly nested model but it more accurately reflects my scenario. If you look at InnerInner you can see I've setup a computed which merely depends on X Y and Z. and a subscription to that computed which prints "test" to the console.

The idea is to throttle these three observables together.

I seems that because ko.computed is being overridden while mapping, throttling doesn't work. The throttle extender returns a wrapped computed and so does knockout.mapping... maybe there's a clash there?

One work around I've found is...

    var marketChange = ko.computed(function () {
        self.X();
        self.Y();
        self.Z();
    });

    marketChange.extend({ throttle: 500 });

    setTimeout(function () {
        marketChange.subscribe(function () {
            console.log('test');
        });
    }, 100);

However, this wouldn't work for a writable computed (which is why it requires a wrapper).

(The delay is required to avoid raising the subscribe method before the first change.)

Any help would be appreciated.

Cheers

Update: I've found that this is not related to throttling
http://jsfiddle.net/x3PLB/3/

zero data value in mapping key field causes uneeded row refresh

I'm using the markup and code below.

If the 'id' field of an object in the 'lrsa' observableArray has a value of 0, then it's row is re-rendered each time the orbservableArray changes in any way.

e.g. if a new row is appended, the both the new row and the row with an 'id' of zero flashes in Firebug, indicating removal and re-rendering. I have confirmed that it is re-rendered - this is not a Firebug-bug.

I would guess that this is a 'zero is false' type bug.

(I have worked around the issue by not using any 0 values for the 'id' field.)

Regards,

Chris.

<ul data-bind="template: { name: 'rowTemplate', foreach: lrsa, beforeRemove: function(elem) { $(elem).slideUp() },
                        afterAdd: function(elem) { $(elem).hide().slideDown() } }"></ul>

var mapping = {
  'lrsa': {
    key: function(data) {
      return ko.utils.unwrapObservable(data.id);
    }
  }
}

foreach not rendering as quickly as it could

I have a coworker that's always going on about how backbone is god's gift, and that I'm retarded for using knockout.
Today, he sent me this:
http://fiddle.jshell.net/ntMdB/139/

it's not apples-to-apples because he's using knockout to setup a bunch of two-way bindings for a one-way view.
So I modified it so that the only thing observable is the array. But the only way I could get it to render any faster is to mess with the item order.
http://fiddle.jshell.net/ntMdB/151/

if i do an array.reverse, it's the same speed as his:
http://fiddle.jshell.net/ntMdB/157/

How can I get the speed of 151 with the same rendering result of 139 and 157?

updateFromJS broken?

Hi,

i'm trying to use updateFromJS to merge data back into a fairly complex viewModel after the data is saved and probably changed on the server.

But it seems updateFromJS is replacing all the data instead of merging. I thought it would merge. So, am i doing something wrong or is it broken?

Here's a sample test case:
http://jsfiddle.net/rBRJZ/2/

Mapping fromJS should support plain arrays

Looks like the fromJS expects the root object to be an object. I very ordinarily want to take:

var data = [{name = "", id = ""}, {name = "", id = ""}, ];
var model = ko.mapping.fromJS(data);

But this always returns an empty array. I shouldn't have to wrap it in an object just to get this to work. This should return an observable array of the inner objects.

Consider switching from Closure Compiler to UglifyJS

For something of knockout.mapping's relatively-small size and complexity, I think Google Closure compiler is causing too much pain for not enough gain. The whole ko.exportSymbol business is unfriendly to new developers, and buys nothing since we are keeping private all non-exported functions. Only simple optimizations are used anyway.

UglifyJS is more or less the gold standard among people not using Closure's advanced optimizations. It's easy to use on Node, which is now cross-platform.

The relative sizes are:

Compiler         | minified | gzipped
-------------------------------------
UglifyJS         | 9667     | 3006
Closure Compiler | 8827     | 2940

Just something to think about :)

Nuget package is broken

When installing the knockout.mapping Nuget package (via the Nuget Package Manager Dialog in VS), I receive the error message "External packages cannot depend on packages that target projects."

This appears to be because the nuspec file is not configuring the correct location of where to store the *.js in the target project.
I believe the nuspec file needs to include a value for the target attribute of the file element.

Something like:

    <file src="build\output\*.*" target="Content\Scripts" /> 
  </files>```

Create method in mappings receive meaningless options.parent for observableArray properties

When mapping arrays, options.parent is set to an observable containing an empty array regardless of the jsObject or target parameter. Normal properties receive the target model as options.parent.

It would be great if the create method would always receive the target model regardless of the type of property being mapped.

Use case: Mappings where access to the target model is required while mapping array elements.

ko.mapping.defaultOptions().include should be an array or string.

2.1.0 was fine, but 2.1.1 causes an exception when running the following snippet:

        ko.mapping.fromJS({
            "firstName": "fjidwj",
            "lastName": "gjfigjp",
            "company": "",
            "homePhone": "",
            "mobilePhone": "32456754356",
            "workPhone": "",
            "faxPhone": "",
            "primaryPhoneNumberName": "Mobile",
            "bestTimeToReach": "Evening",
            "emailAddress": "[email protected]",
            "emailAddressReenter": "[email protected]",
            "__ko_mapping__": {
                "include": [
                    "_destroy"
                ],
                "ignore": [],
                "copy": [],
                "mappedProperties": {
                    "firstName": true,
                    "lastName": true,
                    "company": true,
                    "homePhone": true,
                    "mobilePhone": true,
                    "workPhone": true,
                    "faxPhone": true,
                    "primaryPhoneNumberName": true,
                    "bestTimeToReach": true,
                    "emailAddress": true,
                    "emailAddressReenter": true
                }
            }
        });

Mapping options not used in UpdateFromJS

I've run into what seems to be a bug. I've put an example here. It appears as though the mapping options are not being executed when running the UpdateFromJS method of the mapping plugin.

inner mapping options not respected

See the following jsfiddle for an example of this problem.

http://jsfiddle.net/jamesfoster/HwGgH/

If I have the following object:

function Record(data) {
    var self = this;

    ko.mapping.fromJS(data, {
        copy: ['id']
    }, self);
}

when calling ko.mapping.toJSON(record) everything works as expected, but when the object is wrapped in some other context the id propery is missing

var viewModel = { record: new Record(...) };

ko.mapping.toJSON(viewModel) // id property is missing
ko.mapping.toJSON(viewModel.record) // works

Root-level mapping issue

I've run into an issue where when calling ko.mapping.fromJS a second time around, my browser crashes. I haven't had time to understand enough of what's going on but managed to get it working with this change at line 173

    // Is there only a root-level mapping present?
    if ((options.create instanceof Function) || (options.update instanceof Function) || (options.key instanceof Function) || (options.arrayChanged instanceof Function)) {
        if (!options.hasOwnProperty("")) {
            options = {
                "": options
            };
        }
    }

Notice the !options.hasOwnProperty(""). On the second call to fromJS, I'd get an infinitely recursing options with an empty property name, which was causing the crash.

I'm not sure if this was the correct fix, but I'm passing it along in case it does make sense to you.

Suspicious behaviour of update callback

var someObjectModel = function(data) {
    ko.mapping.fromJS(data, {}, this);
}

var mapping = {
    'prop': {
        update: function(options) {
            var res = options.data ? new someObjectModel(options.data) : null;
            return ko.observable(res);
        }
    }
}

var obj_1 = {
    prop: null
};

var obj_2 = {
    prop: {}
};

var viewModel_1 = ko.mapping.fromJS(obj_1, mapping);
var viewModel_2 = ko.mapping.fromJS(obj_2, mapping);

console.log(typeof viewModel_1.prop, typeof viewModel_2.prop); // function function — Ok
console.log(typeof viewModel_1.prop(), typeof viewModel_2.prop()); // function object — Bug?

But «typeof viewModel_1.prop()» returns «object» if replace «update» on «create».

ko.mapping.updateFromJS and observable returned from create callback

Sample code:

var viewModel = function(options) {
    ko.mapping.fromJS(options.data, {}, this);

    this.func = function() { return true; };
};

var dataForInit = {
    "id": 1,
    "entry": {
        "value": 1
    }
};

var dataForUpdate = {
    "id": 1,
    "entry": {
        "value": 2
    }
};

var model = ko.mapping.fromJS(dataForInit, {
    entry: {
        create: function(options) {
            return ko.observable(new viewModel(options));
        }
    }
});

ko.mapping.updateFromJS(model, dataForUpdate);

value_of(model.entry().value()).should_be(2);

possible fix Anber@c173fe6

toJS should remove __ko_mapping__

Shouldn't toJS on an object build by fromJS remove the ko_mapping property from the resulting object? For now i use the ignore option to exclude that field.

Options for toJS generation (similar to fromJS)

Would it be possible to have the same control over object generation when performing toJS(viewModel) as we have when calling fromJS through the mapping parameter?

In other words, just like we have a "create" mapping when converting to the VM:

var mapping = {
    'children': {
        create: function(options) {
            return new myChildModel(options.data);
        }
    }
}
ko.mapping.fromJS(data, mapping)

could we have a similar mapping:

var mapping = {
    'children': {
        create: function(options) {
            // i realize this is not a good example, but it's illustrative.
            return { id: options.data.id, name : options.data.firstName };
        }
    }
}
ko.mapping.toJS(data, mapping)

Bug when using integer values and checkboxes

I found an issue when mapping a JS array that contains numeric values when used with a foreach template and checkboxes.

It only seems to happen in IE and Google Chrome.

The checkbox doesn't seem to accept the first click, it only works on the second click. After the second click it works properly all the time.

It's pretty hard to explain so here's a jsfiddle with it happening.

http://jsfiddle.net/ccCAP/1/

If the values are changed from being numeric to strings (aka "1" instead of 1) the checkbox works properly.

I'm not sure if this is a knockout bug or knockout.mapping bug, but knockout by itself seems to work fine with numeric values in arrays:

http://jsfiddle.net/gFGn6/1/

Updating or inserting an item in an observable array

this situation is that objects are pumped from a service one at a time and stored in an array. Also, updates to those objects are received one at a time. When there is a key defined for the mappedObservableArray, it would be nice if fromJS inserted or updated based on key match.

for instance:

   var vm =ko.mapping.fromJS( [ ko.mapping.formJS({name:'matt', age:20}) ], {
        key:function(data) {
            return ko.utils.unwrapObservable(data.name);
        }
    });

    ko.mapping.fromJS(ko.mapping.fromJS({ name: 'jim', age: 23 }), vm); //should insdert jim into the array

    ko.mapping.fromJS(ko.mapping.fromJS({ name: 'matt', age: 23 }), vm); //should change matt's age to 23

I use this pattern quite a lot.
currently, I'm doing this:

    var index = vm.mappedIndexof(data);
    if(index < 0) { 
         vm.push(ko.maping.fromJS(data));
    } else {
        ko.mapping.fromJS(data, vm()[index]);
    }

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.