如何使用唯一数据和 return 值填充 select 选项作为 selected 项目?

How to populate select options with unique data and return a value as selected item?

我有一个数据对象传递给 observableArray,看起来像这样:

self.Players = ko.observableArray([{

    "LastName": "Jordan",
        "FirstName": "Michael",
        "Team": "Chicago Bulls",
        "Jersey": "23"
}, {
    "LastName": "Duncan",
        "FirstName": "Tim",
        "Team": "San-Antonio Spurs",
        "Jersey": "21"
}, {
    "LastName": "Duncan",
        "FirstName": "Tim",
        "Team": "San-Antonio Spurs",
        "Jersey": "21"
}, {
    "LastName": "Jordan",
        "FirstName": "Michael",
        "Team": "Chicago Bulls",
        "Jersey": "23"
}
    ]);

我需要用每个球员的唯一名字和姓氏填充Select Options,同时还将球衣值作为选定值传递。数据可以重复。

所以每次选择球员时,我都需要将球衣号码传递给:

self.SelectedPlayer = ko.observable('');

我试图做这样的事情:

self.UniquePlayers = ko.computed(function () {
       var uniquePlayers = ko.utils.arrayMap(self.Players(),

           function (data) {
               return data.FirstName + ' ' + data.LastName
           });

       return ko.utils.arrayGetDistinctValues(uniquePlayers).sort();
   });

这是有效的,除了我没有得到球衣,因为它没有被归还。

我也试过返回数据对象:

           function (data) {
               return data
           });

这允许我指定 optionsValueoptionsText

  <select class="form-control" 
  data-bind="options: UniquePlayers,
             optionsText: function(item){return item.FirstName + ' ' + item.LastName},
             optionsValue: 'Jersey',
  value: SelectedPlayer"></select>

但我没有获得唯一值,我无法访问 optionsValue:

self.SelectedPlayer().Jersey;

如何显示唯一球员的名字和姓氏,并将球衣作为 optionsValue?

在 viewmodel 中编写匿名函数不是最好的主意,而且我认为你的代码过于复杂,我认为在这种情况下你真的不需要 ko.computed,无论如何,为什么不呢你喜欢这样的东西:

function (data) {
    var obj = data;
    obj.fullName = data.FirstName + ' ' + data.LastName;
    return obj;
});

如果你会创建一个 jsfiddle 演示,它会更容易玩。

您不能对包含对象的数组使用 ko.utils.arrayGetDistinctValues()。此函数仅适用于原始值,另一方面,对象可以具有相同的属性,但本身并不相同。

使用这样的东西:

self.UniquePlayers = ko.computed(function () {
    var uniquePlayers = [], index = {};

    ko.utils.arrayForEach(self.Players(), function (p) {
        var fullName = p.FirstName + ' ' + p.LastName;
        if ( !(fullName in index) ) {
            uniquePlayers.push({text: fullName, player: p});
            index[fullName] = true;
        }
    });

    return uniquePlayers.sort();
});

<select class="form-control" data-bind="
    options: UniquePlayers,
    optionsText: 'fullName',
    optionsValue: 'player',
    value: SelectedPlayer
"></select>

当然,预先计算一次 fullName 值然后在视图模型初始化期间存储在播放器对象中是明智的。