Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Knockout Mapping - fromJS - failing on a simple example

I'm trying to figure out what I'm misunderstanding with Knockout's mapping library. I've stripped it down to a simple example, and still can get it to fail (rather, not update with the mapped variables) with the fromJS call.

What am I getting fundamentally wrong in this example?

// Here's my view model
var ViewModel = function() {
    this.firstName = ko.observable('first');
    this.lastName = ko.observable('last');
};

var myVM = new ViewModel();

ko.applyBindings(myVM); // Apply to Knockout (works)

myVM.lastName('maiden name'); // Test an update (works)

var newData = {firstName: 'new', lastName: 'person'};

// Try update the ViewModel
ko.mapping.fromJS(newData, myVM); //(No update, or error)

// Intended result - UI updates to 'new person'

And the corresponding view:

<div class='liveExample' >   
    <p>First name: <input data-bind='value: firstName' /></p> 
    <p>Last name: <input data-bind='value: lastName' /></p> 
</div>

My JS Fiddle example.

like image 613
Overflew Avatar asked Sep 12 '13 06:09

Overflew


People also ask

What is Ko applyBindings?

For example, ko. applyBindings(myViewModel, document. getElementById('someElementId')) . This restricts the activation to the element with ID someElementId and its descendants, which is useful if you want to have multiple view models and associate each with a different region of the page.

What is KO in knockout JS?

Reacting to a specific observable event with “ko. when” This advanced technique for working with observables was added in Knockout 3.5. Sometimes, rather than reacting to every change to an observable, you just need to know when the observable arrives at a specific value. This is what ko.when makes easy.


2 Answers

The ko.mapping.fromJS handles the parameters a little bit tricky (see my answer here), so the second parameter is normally the mapping options:

ko.mapping.fromJS(newData, {} /* mapping options */, myVM); 

Demo JSFiddle.

like image 161
nemesv Avatar answered Nov 07 '22 23:11

nemesv


I found how to use only 2 data parameters.

Create your ViewModel as a mapping of your original data, then use ko.mapping.fromJS(data, ViewModel).

UPDATED jsFiddle

Explanation

Knockout uses a property called mappingProperty = "__ko_mapping__" to identify when data has been previously mapped. If found, it will set the second parameter as the target (ViewModel in this case).

Excerpt from the debug version of ko.mapping.js:

var mappingProperty = "__ko_mapping__";

[...]

if (arguments.length == 2) {
  if (arguments[1][mappingProperty]) {
    target = arguments[1];
  } else {
    options = arguments[1];
  }
} 
like image 40
I.G. Pascual Avatar answered Nov 08 '22 00:11

I.G. Pascual