Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug with initial value when using naming template or foreach inside select tag #1243

Open
Kasheftin opened this issue Dec 8, 2013 · 6 comments

Comments

@Kasheftin
Copy link

I want to use named template inside the <select> tag. The reason is my options have nested structure, so I call this template inside itself for each child recursively.

We can specify all options manually inside select tag, and this case <select> gets the properly value after initialization, here's the example: http://jsfiddle.net/eHE9J/.

But if we move options to any named template or even include foreach binding inside the select tag, initial value is dropped - it seems, foreach or template binding applied "after" the select initialization. Here's the example with named template: http://jsfiddle.net/eHE9J/1/, and here's it with foreach binding http://jsfiddle.net/eHE9J/2/.

@mbest
Copy link
Member

mbest commented Dec 8, 2013

The solution is to bind the inner content before the value binding. This can be done using a custom binding that just binds the inner content and is listed before value.

ko.bindingHandlers.bindInner = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        ko.applyBindingsToDescendants(bindingContext, element);
        return { controlsDescendantBindings: true };
    }
};
<select data-bind="bindInner, value:v1">

http://jsfiddle.net/mbest/eHE9J/3/

I think it would be good to include a binding like this in Knockout and document this approach.

@mbest
Copy link
Member

mbest commented Dec 8, 2013

In my Knockout fork, I set up the value binding to always run after the inner content by using the contentUpdate binding flag. But implementing this in the current Knockout would not be trivial.

@mbest mbest mentioned this issue Jan 1, 2014
5 tasks
@mbest
Copy link
Member

mbest commented Jan 2, 2014

The example above appears to work with Knockout 2.3.0, but it still doesn't. http://jsfiddle.net/eHE9J/4/ Although the selection is set correctly, the model value has still been reset to "0".

@SteveSanderson
Copy link
Contributor

I wonder if dynamically generating <options> elements from a complex structure like this is really going to work robustly with value anyway. For one thing it can violate the expectation that <options> nodes don't vanish while they are selected, meaning that the model and UI can get out of sync. In that sense it's fortunate we don't already have accidental partial support for it, like we would if value ran after its children were bound.

A sounder technique, I think, would be generating a data structure of options in your viewmodel as a ko.computed. This can take account of whatever recursion is necessary to produce the full list, perhaps indenting the text to reflect its depth in some tree. Then you just use a regular options binding on your <select> element. @Kasheftin - could you say whether you tried this, and if so, in what way it wasn't sufficient?

Changing value to somehow understand that the descendant nodes can mutate at any time sounds a bit impractical.

@Kasheftin
Copy link
Author

@SteveSanderson , yes, I created a computed observable with required options and used it with regular options binding. This is more natural way, and this way everything works perfectly.

@mbest
Copy link
Member

mbest commented Jan 14, 2014

@SteveSanderson, Are you saying that we shouldn't support generating <option>s using foreach? I'm asking because you previously responded to a different issue oppositely: #382 (comment).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants