首页 > 解决方案 > 淘汰赛 Js 多选绑定

问题描述

我在 KnockoutJs DropDown 列表中绑定了一组国家/地区列表,如下所示

在此处输入图像描述

在 knockoutJS 中,一旦在一个列表中选择了该国家/地区,如何在所有其他国家/地区列表中删除该国家/地区?

标签: javascriptjqueryknockout.js

解决方案


如果您拥有所有地区,则可以动态确定还有哪些国家可供选择。逻辑:

  • 收集所有区域及其选择
  • 从该列表中删除您当前正在查看的区域
  • 采取所有可用的国家
  • 从该列表中删除由另一个区域选择的任何国家/地区

在代码中:

const getAvailableCountries = (allRegions, thisRegion) => {
  const otherRegions = allRegions.filter(r => r !== thisRegion);
  const inUseByOtherRegions = new Set(
    otherRegions.flatMap(r => r.selectedCountries())
  );
  
  return countries.filter(c => !inUseByOtherRegions.has(c));
}

困难的部分是获得对“兄弟区域”的引用。我的建议是为此使用敲除的绑定上下文:

data-bind="options: getAvailableCountries($parent.regions, $data)"

在一个可运行的例子中:

const countries = [ "C1", "C2", "C3", "C4", "C5" ];
const regions = ["R1", "R2", "R3" ];

const getAvailableCountries = (allRegions, thisRegion) => {
  const inUseByOtherRegions = new Set(
    allRegions.flatMap(r => r === thisRegion
      ? []
      : r.selectedCountries()
    )
  );
  
  return countries.filter(c => !inUseByOtherRegions.has(c));
}

const vm = {
  regions: regions.map(
    regionId => ({
      regionId,
      
      getAvailableCountries,
      selectedCountries: ko.observableArray([])
    })
  )
}


ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<div data-bind="foreach: regions" style="display: flex; justify-content: space-between;">
  <div>
    <h2 data-bind="text: regionId"></h2>
    <select data-bind="
      options: getAvailableCountries($parent.regions, $data),
      selectedOptions: selectedCountries" size="5" multiple="true"></select>
  </div>
</div>


推荐阅读