I'm feeding my options off an AJAX
request, while the value is in the selection initially. However Knockout
seems to delete values that aren't in the options on binding.
Example: http://jsfiddle.net/EVzrH/
Knockout
seems to use selectExtensions
(line 1699 of v3) to read and write the selected option. In this new values are matched to indexes, and returned by again getting the index and matching to data.
How can I save my data from being lost?
Generally, I handle this by prepopulating the observableArray with the current value (no need for the text, since you wouldn't likely know it yet).
Like:
var viewModel = {
val: ko.observable(1),
opts: ko.observableArray([{ Id: 1 }])
};
Then, let the observableArray get populated with the actual values when it returns.
For a more generic solution, you could use a custom binding as described in the second part of this answer: Knockout js: Lazy load options for select
This would pre-populate the observableArray for you and take into account that you may or may not have optionsValue
set.
I can see 2 possible options here. First is to fill opts arrray before applying bindings:
var viewModel = {
val: ko.observable(1),
opts: ko.observableArray([])
};
viewModel.opts([
{ Id: ko.observable(1), Text: ko.observable("abc") },
{ Id: ko.observable(2), Text: ko.observable("someVal") },
{ Id: ko.observable(3), Text: ko.observable("other") }
]);
ko.applyBindings(viewModel);
Here is fiddle: http://jsfiddle.net/EVzrH/1/
Or if for some reason you cannot populate it before applying bindings you can just save value and them assign it again:
var viewModel = {
val: ko.observable(1),
opts: ko.observableArray([])
};
var value = viewModel.val();
ko.applyBindings(viewModel);
viewModel.opts([
{ Id: ko.observable(1), Text: ko.observable("abc") },
{ Id: ko.observable(2), Text: ko.observable("someVal") },
{ Id: ko.observable(3), Text: ko.observable("other") }
]);
viewModel.val(value);
Here is a fiddle: http://jsfiddle.net/EVzrH/2/
Either set the value after populating the options, or subscribe to the options:
viewModel.opts.subscribe(function() {
viewModel.val(1);
});
http://jsfiddle.net/gCyP6/
I've managed to get it working the way I wanted by commenting out some of the knockout code to avoid ko.dependencyDetection.ignore
.
http://jsfiddle.net/EVzrH/3/
ko.bindingHandlers['value']['update'] = function (element, valueAccessor) {
ko.bindingHandlers['options']['update'] = function (element, valueAccessor, allBindings) {
Only problem is that it isn't minified, so switching to the minified library does not work.