How do I make options binding work with ko.mapping.fromJS?

165 views
Skip to first unread message

philipmat

unread,
Apr 10, 2012, 5:48:11 AM4/10/12
to knock...@googlegroups.com
I'm sure I'm doing it wrong, but it seems that if the 'value' is the result of a mapping.fromJS, the binding will not select that value in the combo box.
I've capture my problem in this jsfiddle:  http://jsfiddle.net/88eLa/4/

I get from two separate URL the list of states (e.g. [{Id: 'CA', Name: 'California'},...]) and my model: { State: {Id: 'TX', Name: 'Texas'}}.

If my view-model is something like this:
function ViewModel() {
  var self = this;
  self.State = ko.observable();
  self.ref = { States : [] }

  // this doesn't work:
  self.ref.States = statesJson;
  ko.mapping.fromJS(modelJson, {}, self);
}

and neither does this: 
  ...
  var states = ko.mapping.fromJS(statesJson);
  self.ref.States = states;
  ko.mapping.fromJS(modelJson, {}, self);


By "doesn't work" I mean the combo gets populated, but the proper state never gets selected.

Sure, I can set it directly self.State(model.State), but if that's the answer, maybe I'm missing what the point/use-cases for ko.mapping are?

(I think the problem stems from the ko.selectExtensions.writeValue, where "ko.selectExtensions.readValue(element.options[i]) == value" seems to always be false in both of the approaches above.)

NTB

unread,
Apr 12, 2012, 1:30:54 AM4/12/12
to knock...@googlegroups.com
Without seeing what exactly your HTML data-bind looks like, or where you're calling applyBindings(), I would posit that your data-bind should make use of the "optionsValue" binding to specify what property acts as the underlying value for each option.  That would mean your State would now need just be Id instead of the whole object of course, but the reason it's never selecting the appropriate option is because although the properties of the ajax objects are the same, the state object and the matching object in the options array are technically not the same object.  That's the approach I take anyway.

josh

unread,
Apr 12, 2012, 4:31:36 AM4/12/12
to KnockoutJS
@NTB: Your interpretation sounded right to me. I tested it to be sure
(trying to learn this tool), confirmed.
--> Setting the State property to a new object does not match any of
the existing objects in the ref.States array.
--> Confirmed that by adding optionsValue = 'Id', the State property
holds the string value of ID and will match when updated and change
the <select...combo.

@phillipmat: I was able to get the mapping to work too, but only by
running ko.applyBindings after completing mapping.
see...http://jsfiddle.net/88eLa/11/

From the doc I was not sure if calling ko.applyBindings was intended
or if it is an efficient thing to do. Also not really sure of the
parameter list for ko.mapping,fromJS().
Would be nice to spell that out in one place in the doc.
But it seems that using mapping without that just produces a new
ViewModel Instance that has the right new values but is not used by
ko.

Maybe someone else can comment on the intent / validity of using
ko.applyBindings() again.
Reply all
Reply to author
Forward
0 new messages