Knockoutjs: refresh bindings after populating select list

17,071

So as John Earles said, adding items to the select list doesn't trigger a 'change' event. I have concluded that's actually a Good Thing. From one of the (really good) Knockout tutes:

Bindings catch DOM events and correspondingly update viewmodel properties.

That's the reverse behaviour from what I want! So I've stuck with the callback. At present it just calls applyBindings(). You can see an example in this revision of the original fiddle (callbacks etc omitted for clarity).

Share:
17,071
Julian Suggate
Author by

Julian Suggate

Updated on June 14, 2022

Comments

  • Julian Suggate
    Julian Suggate about 2 years

    I feel like this must have been asked before, but I've looked at

    and

    But those problems weren't quite the one I'm facing.

    In my view I receive a viewmodel from an ajax call. In that object is a country ID. In a subsequent ajax call, I retrieve a list of countries (name and ID) and populate a select box from the list.

    The select box is bound to the viewmodel's country ID using

    <select data-bind="value: CountryId"/>
    

    But when I populate the dropdown, the viewmodel's country is not pre-selected. I have to manually call ko.applyBindings(vm), which is a problem because the data is populated from a jQuery plugin that handles cascaded select boxes. It doesn't have references to the viewmodel (nor do I want to provide it). I could expose a callback, but that's a bit yawn.

    I have created a fiddle that illustrates this problem more cleanly. If you click on the Test Select button, you will notice that the dropdown is preselected to Item 0. Uncomment the line in the js panel, and Bob's your uncle.

    What am I not getting here? Isn't this a basic knockout feature?

    -Jules

    • John Earles
      John Earles over 12 years
      I don't think you are going to be able to do what you are trying to do. The value binding will set up a listener on 'change' for the select, to react when you select a new option. You are just adding options to the select, so Knockout has no way of knowing that it should do anything. Even if it did know, it would reset value to 0, because your options don't specify which row is selected - meaning 0 will be selected.
    • Julian Suggate
      Julian Suggate over 12 years
      I think you may be right. I've gone with the callback mechanism for now, however I'm running into a problem with that. Have updated the question with new info.
    • Julian Suggate
      Julian Suggate over 12 years
      Scratch that, I have solved the secondary problem. Will post an answer to this question shortly.
    • Julian Suggate
      Julian Suggate over 12 years
      So as you said, adding items to the select list doesn't trigger a 'change' event. I have concluded that's actually a Good Thing. From one of the (really good) Knockout tutes: > Bindings catch DOM events and correspondingly update viewmodel properties. That's the reverse behaviour from what I want! So I've stuck with the callback. At present it just calls applyBindings(). You can see an example in this revision of the original fiddle (callbacks etc omitted for clarity).
  • Julian Suggate
    Julian Suggate over 12 years
    Hmm, interesting. Not sure I like the idea of putting logic into comments though! How would this behave if the select list is populated, and then repopulated with a new set of values?
  • John Earles
    John Earles over 12 years
    You don't have to use the "containerless" syntax... you could also add the "if" to a container div. If the select list items are changed Knockout will re-evaluate the bindings. I've updated my example to show that syntax, and added a second update and clear buttons. jsfiddle.net/jearles/nw4cH/77
  • Julian Suggate
    Julian Suggate over 12 years
    That's a nice example, thanks. As you can see though, on the second update the bindings update from DOM -> viewmodel (selected item changes to 5), rather than the other way around. I've gone with the manual approach for now. Thanks for your help getting me to see what's going on. I'd mark your comment to the OP above as an answer, but StackOverflow doesn't have that as an option?