knockout / knockout

Knockout makes it easier to create rich, responsive UIs with JavaScript
http://knockoutjs.com/
Other
10.45k stars 1.52k forks source link

preset value will not be set when value is put before options parameter #149

Closed Kensuging closed 12 years ago

Kensuging commented 13 years ago

If value parameter is put before options, preset value will not be ignored.

In case of value before options parameter: http://jsfiddle.net/PkK6s/2/ In case of value after options parameter: http://jsfiddle.net/PkK6s/3/

Please see lines of posts, https://groups.google.com/group/knockoutjs/browse_thread/thread/a0a145b3855e2eb4/a5ff2fb5ba3c53d9#a5ff2fb5ba3c53d9.

Regards.

stevekrile commented 13 years ago

I have viewed the same behavior. Changing the order of the parameters in my select tag changes the KO behavior of my observable.

My expectation would be that KO would evaluate the "contents" of the select object before evaluating the "value" of the selected item.

SteveSanderson commented 13 years ago

Thanks for reporting this. I think others have identified the same issue too. I'll look into improving this!

mbest commented 12 years ago

This specific issue is already fixed in Knockout.

But there is still an issue that occurs when value is bound before options: that removing the currently selected item from the array will not update the value. If value is specified after options, removing the currently selected item from the array will clear the value (set it to undefined).

There's also an issue with value and options that occurs regardless of the order: Removing all items from the array will not clear the value (but "removing" them a second time will clear the value).

brandonwittwer commented 12 years ago

I'm noticing as well, no matter where the bindings are in the data-bind string, if the options are grabbed via ajax and don't arrive in a timely fashion, the observable bound to the 'value:' handler gets set to undefined before the options finally come back.

Example Fiddle: http://jsfiddle.net/bsingin64/GvuZu/

Only trick I could reasonably come up with would be to wrap my value in an array and use the selectedOptions binding instead. This is not an effective solution for my app.

To load an initial selection, could I suggest the addition of a selectedOption binding or the modification of the selectedOptions to accept a primitive type in addition to an array? Then possibly the value binding handler gets ignored whenever these are in use??

mbest commented 12 years ago

@bsingin64 - The value binding works as designed (mostly) in that it will be set to match whatever is currently selected. If there are no items, it will be cleared. I would suggest that selectedOptions is incorrect here. The proper way to handle this is to delay binding until the options are set. One way to do this (in Knockout 2.0+) is to use the if binding as I've done here: http://jsfiddle.net/mbest/GvuZu/1/ You could also just set the value observable after you set the options (in your ajax callback).

brandonwittwer commented 12 years ago

The controlflow binding is an interesting solution. I didn't know that bindings within these blocks arent evaluated until the block evaluates truthy. Hmm.. It causes visual pops, which would be nice to avoid in my application. I'm starting to see the light.

Since i'm binding to an observable representation of my model, I really don't want to have to deal with setting a separate observable after the options come back. I realize this would work, but it would tarnish my model representation (trueValue + selectValue observables would have to both work in concert... annoying). How crazy would a "delayUntil option within our bindings be? data-bind="value:{delayUntil:OptionsObservable().length, value:selectedOption}. I'm just throwing things out there. I know there are less pretty ways to achieve, as you mentioned, but i'm looking for something that makes it wonderfully Knockout-y and easy to implement.

mbest commented 12 years ago

I like the idea of a delayed binding option. Here's your example with a delayBind binding controlling the value binding: http://jsfiddle.net/mbest/E2cjL/

My update uses KO 2.0.0 instead of 1.2.1. I changed your selected items arrays to use integers instead of strings (otherwise they weren't matching in the new version of KO).

brandonwittwer commented 12 years ago

I'm impressed by your turn around on this. Super fast! The flexibility you built into this truly makes this a powerful option to the controlflow solution that is working OOTB.

I'm almost certain this solution will work for my situation.

I can't complain, but it is worth mentioning, this whole situation with select boxes is a little rough around the edges. While this solution works and is very flexible, it still feels like a patch. While I understand the catch 22, it still feels like the value binding needs to get a chance to "retry" itself after an empty option set is replaced by a populated one. I'm shooting in the wind, but the argument is really only for developer adoption.

Either way, no complaints here. Thanks again for taking my idea and making it come to fruition... I should pay you... !!!

brandonwittwer commented 12 years ago

See this, one step further example where the delaybind needs to figure out how to jump back in and do it's magic again.

http://jsfiddle.net/bsingin64/nQGzU/

notice, once the list of items is cleared, the selected value is also cleared, but when the items come back, the selected item does not... unless it's using the selectedOptions binding.

mbest commented 12 years ago

See this, one step further example where the delaybind needs to figure out how to jump back in and do it's magic again.

delayBind won't be able to do that. You'll have to use if around the select.

mbest commented 12 years ago

BTW, this issue was discussed already here: #250

mbest commented 12 years ago

I think it might be useful for the value binding to have the option to allow a value that isn't in the select list.

mbest commented 12 years ago

I'd like to see the value/options issues cleared up in v2.2. Even though the original issue described here is fixed, there are still other issues that Brandon and I brought up that are important.

SteveSanderson commented 12 years ago

Do we have a single issue to represent "make bindings run in a particular order"? I'm not committed to changing that behavior in 2.2, but in any case it would be nice to have an issue to represent these kinds of requests, then we could close this as a duplicate.

mbest commented 12 years ago

I have considered this one to be the main issue. Of course, it will require some general support for ensuring the order of certain bindings, but the important part is the bindings that are order-dependent are handled.

mbest commented 12 years ago

I've created https://github.com/SteveSanderson/knockout/issues/552 to track the general binding ordering problems in Knockout. I'll close this one.