如何使用 Knockout JS 数组映射根据输入条件使 select 选项默认绑定?

How to make a select options binding default based on input conditions using a Knockout JS Array Map?

我正在使用 Computed ObservableArray Map 将数据绑定到选择选项。

使用下面的代码结构,如何在 select 选项中将国家设为默认值?例如:如果用户来自 Albania,则将默认国家/地区设置为 Albania。请注意,我正在使用并需要 selected 值作为另一个函数的参数。

完整代码:

(function(){

    var self = this;

    self.SelectedCountry = ko.observableArray([]);
    self.CountryData = ko.observableArray([]);

    $.getJSON('https://restcountries.eu/rest/v1/all', function(data){

        self.CountryData(data);

    });

    function viewModel(){

      // Add some possible logic to make country default based on input
      // from user. E.g. If data.alpha3Code === '1234'

        self.Countries = ko.computed(function () {
            return ko.utils.arrayMap(CountryData(),

                    function (data) {

                        return {

                            Name: data.name + ' ' + data.capital,
                            value: data.alpha3Code
                        }

                    });

        }).extend({notify: 'always'})
    }

    self.Location = ko.computed(function () {
        if (self.SelectedCountry()) {
            return ko.utils.arrayFilter(CountryData(), function (item) {
                return item.alpha3Code === self.SelectedCountry().value;
            });
        }
    });

    ko.applyBindings(new viewModel());

})();

Working example on JSFiddle:

您的代码有很多问题。

  1. SelectedCountry 应该是一个 observable,而不是一个 observableArray
  2. viewModel 不是正确的构造函数,因此不应使用 new 调用(我刚刚完全摆脱它)
  3. 您应该将 self 传递给 applyBindings
  4. 您可能需要 optionsValue: 'value' 在您的 select 绑定中
  5. self 应初始化为空对象。 this 是你完成它的全局对象。你可能打算把它全部放在你的构造函数中。
  6. 您的计算中 CountryData 前面需要 self
  7. Location 应该只是 return 名称,而不是数组,因为如果 SelectedCountry 没有定义,你就没有数组并且你的 [0] 中断

完成所有这些后,您只需设置 SelectedCountry 的值,select 将相应更新。唯一的技巧是,您需要添加另一个绑定,valueAllowUnset: true 到 select 以告诉它您选择的值可能不存在(它不会,至少在加载数据之前)。

(function() {

  var self = {};

  self.SelectedCountry = ko.observable('BHR');
  self.CountryData = ko.observableArray([]);

  $.getJSON('https://restcountries.eu/rest/v1/all', function(data) {

    self.CountryData(data);

  });

  self.Countries = ko.computed(function() {
    return ko.utils.arrayMap(self.CountryData(),

      function(data) {

        return {

          Name: data.name + ' ' + data.capital,
          value: data.alpha3Code
        }

      });

  }).extend({
    notify: 'always'
  })

  self.Location = ko.computed(function() {
    if (self.SelectedCountry()) {
      var match = ko.utils.arrayFilter(self.CountryData(), function(item) {
        return item.alpha3Code === self.SelectedCountry();
      })[0];
      if (match) {
        return match.name;
      }
    }
  });

  ko.applyBindings(self);

})();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<select data-bind="options: Countries, optionsText: 'Name', optionsValue: 'value', valueAllowUnset: true, value: SelectedCountry"></select>

<p>Welcome! You are from:</p> <span data-bind="text: Location()"></span>