【问题标题】:How to make a select options binding default based on input conditions using a Knockout JS Array Map?如何使用 Knockout JS Array Map 根据输入条件设置选择选项绑定默认值?
【发布时间】:2015-12-10 21:28:21
【问题描述】:

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

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

完整代码:

(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:

【问题讨论】:

    标签: javascript jquery knockout.js knockout-2.0


    【解决方案1】:

    这里的代码有很多问题。

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

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

    (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>

    【讨论】:

    • 非常感谢您的精彩回答和提示。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-28
    • 2019-05-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-04
    • 2018-08-09
    相关资源
    最近更新 更多