Example Problem: http://jsfiddle.net/whxD3/12/
In knockout I have a select box that I want to use optgroups in. This select box can be rebound depending on what “section” you are currently in. I’m finding due to the way knock is doing its binding order the following problems occur:
HTML:
<div>
<a href="#" data-bind="click: page1">Section 1</a>
<a href="#" data-bind="click: page2">Section 2</a>
</div>
<hr/>
<div data-bind="with: activepage">
<select data-bind="value: selectedItem">
<optgroup label="Items">
<!-- ko foreach: items() -->
<option data-bind="value: $data, text: $data"></option>
<!-- /ko -->
</optgroup>
<optgroup label="Constants">
<option value="foo">foo</option>
</optgroup>
</select>
<br/><br/>
Selected Item: <span data-bind="text: selectedItem"></span>
</div>
JavaScript:
function SubPageViewModel(name) {
this.name = name;
this.items = ko.observableArray(["one", "two", "three"]);
this.selectedItem = ko.observable();
}
function PageViewModel() {
this.pages = [new SubPageViewModel("page1"), new SubPageViewModel("page2")];
this.activepage = ko.observable(this.pages[0]);
this.page1 = function() { this.activepage(this.pages[0]); }
this.page2 = function() { this.activepage(this.pages[1]); }
}
ko.applyBindings(new PageViewModel());
-
Because I’m using a comment foreach to fill a select box the data binded selected value of the drop down in null initially even though an item is selected
-
When you navigate away from the current section and navigate back the selected value is reset to null.
I believe this is happening because knockout is binding the selected value before the comment foreach fills the selected box so its value is set to null. Then once the select box is filled nothing is triggering an update to update the selected value.
How do I get around this problem?
You’re right about the binding order causing a problem. There’s a way to force the descendant bindings to happen first, though. You can do this by creating a custom binding that just binds the descendants and add that binding before the
valuebinding.Here is the custom binding:
Here’s how you’ll use it:
Here is your example using this (and with other cleanup): http://jsfiddle.net/mbest/whxD3/14/