0

したがって、計算されたオプションを持つ Select があります。選択オプションが変更されるたびにデフォルトを選択したい。

私はそれを行ういくつかの異なる方法を試しました:

  • リストを購読する - リストが返される前に呼び出されるため、オブザーバブルの値が変更されますが、リストが後で変更されるため、正しくレンダリングされません。

  • afterRender - このタイプのバインディングでは機能しません。

  • OptionsafterRender - 以下のフィドルのように機能しますが、レンダリング全体で一度だけではなく、個々のアイテムごとに呼び出されるため、これを行うには間違った方法だと思います。

var rawData = [{
  Type: "1",
  Color: "Blue",
  Name: "Blue Car"
}, {
  Type: "2",
  Color: "Blue",
  Name: "Blue House"
}, {
  Type: "1",
  Color: "Red",
  Name: "Red Car"
}, {
  Type: "2",
  Color: "Red",
  Name: "Red House"
}];
var viewModel = {
  FirstSelectedOption: ko.observable(),
  SecondSelectOptions: null,
  SecondSelectedOption: ko.observable(),
  Load: function() {
    var self = viewModel;
    self.SecondSelectOptions = ko.computed(function() {
      var selected = self.FirstSelectedOption();
      var returnValue = new Array({
        Type: "*",
        Color: "All",
        Name: "All"
      });
      var filteredlist = ko.utils.arrayFilter(rawData, function(item) {
        return item.Type == selected;
      });
      returnValue = returnValue.concat(filteredlist);
      return returnValue;
    }, self);
    self.SecondSelectedOption.SetDefault = function() {
      // we want the default to always be blue instead 'all', blue might not be the last option
      var self = viewModel;
      var defaultoption = ko.utils.arrayFirst(self.SecondSelectOptions(), function(item) {
        return item.Color == "Blue";
      });
      self.SecondSelectedOption(defaultoption);
    };
  }

};

viewModel.Load();
ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select data-bind="value: FirstSelectedOption">
  <option value="1">Car</option>
  <option value="2">House</option>
</select>
<br/>
<select data-bind="options: SecondSelectOptions, 
                   optionsText: 'Name',                               
                   value: SecondSelectedOption,
                   optionsAfterRender: SecondSelectedOption.SetDefault"></select>

http://jsfiddle.net/dt627rkp/

頭のてっぺんから考えることができる唯一の方法は、カスタムバインディングです...そして、オプションバインディング全体を再実装しなければ、それが本当に可能かどうかさえわかりません。
私はこれを最初に望んでいるわけではありません。私が見逃しているベストプラクティス/方法はありますか?

4

1 に答える 1

0

optionsAfterRenderコールバックは、オプション (要素) と項目 (オプションにバインドされたデータ) の 2 つのパラメーターを渡します。コールバックはすでにオプションをループしているため、繰り返す必要はありません。

self.SecondSelectedOption.SetDefault = function (option, item) {
   var self = viewModel;
   if (item.Color === 'Blue')
       self.SecondSelectedOption(item);
};

更新されたフィドル
参照:ドキュメントから

編集:そうは言っても、オプションを毎回再評価したくない場合は、最初のメソッドでchangeイベントをバインドすることもできます。このコードの「問題」に直面した場合、おそらくこのフィドルのように、データを個別の配列に前処理するでしょうsetDefault<select>

于 2015-03-06T22:34:22.590 に答える