LoginSignup
6
8

More than 5 years have passed since last update.

Knockout.jsで動的なselectのデフォルト値を設定する

Last updated at Posted at 2015-04-21

ものすごくハマったので、メモ。
Knockout.jsでselectを作るのはお手軽で、デフォルト値を設定するのもvalueを使うだけでいいのですが、Ajaxで取得したJSONを使ってフォームを更新しようとしたところ、デフォルトの値が設定されなくて困りました。

Before

まずはView

#new_foo data-bar_id="1"
  select.select.form-control(
    name="foo[bar_id]"
    data-bind="options: bars, optionsText: 'name', optionsValue: 'id', optionsCaption: '選択してください', value: default_bar_id")

そしてViewModel

class window.BarViewModel
  constructor: (bar_id)->
    @bars = ko.observableArray()
    @default_bar_id = ko.obserbable(bar_id)

$ ->
  # selectのデフォルト値になる値を取得
  bar_id = $('#new_foo').data('id')

  # bindingしておく
  bar_vm = new BarViewModel(bar_id)
  ko.applyBindings(bar_vm)

  # selectのoption用のデータを取得
  $.getJSON '/bars.json', (data) ->
    bar_vm.bars(data)

これで、selectのデフォルトがbar_idの値の項目になるであろう…と思ったらなりませんでした。おそらく、すでに一度data-bindの中を評価した後なので、optionsの内容が変わってからまたvalueを評価してもおかしなことになるからでしょう。

After

これを解決するには、if文を使って表示・非表示を設定します。

#new_foo data-bar_id="1"
  /! ko if: bars().length > 0
  select.select.form-control(
    name="foo[bar_id]"
    data-bind="options: bars, optionsText: 'name', optionsValue: 'id', optionsCaption: '選択してください', value: default_bar_id"
)
  /! /ko

if文で要素の表示・非表示を設定すると、非表示の際には要素自体がなくなります。そのため、trueになった際には、要素が再構成されるため、data-bindの設定が再評価されるのだと思います。

Ajaxでselectの内容を変更する際には、気をつけましょう!

参考URL

6
8
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
8