【问题标题】:Disabling/Removing Select Options created via a Knockout options binding禁用/删除通过敲除选项绑定创建的选择选项
【发布时间】:2013-08-14 05:55:19
【问题描述】:

我有一系列可供用户选择的选项,我可以通过可观察数组对其进行跟踪。数组本身来自一个模型,我通过 Knockout Mapping 扩展 (ko.mapping.fromJS) 将其引入淘汰赛。一切正常。

解释这将变得冗长,并且可能会导致更多混乱,请参见下图:

基本上:

  • 我有一个 Web 输入表单(它是一种配置器)
  • 项目列表非常大,我会说可以将 10 个左右的项目添加到配置中
  • 当用户添加一个项目时,我将一个默认的“项目 A”推送到绑定到选项的数组中,并且渲染得很好。
  • 我试图做的是在项目 A 添加一次后将其从可选择状态中删除。 如果删除了,应该可以重新添加
  • 所有这一切发生的方式是通过 KO observables - 一个跟踪可用选项,另一个跟踪“选定”选项。正如我所说,一切正常,我正在尝试根据请求对其进行调整。

最初 - 我在想 - 我会让用户添加重复项并通过验证处理重复项 - 如果这是唯一的选择,我可能会退回到它。

我发现了“Post-processing the generated options”,但提供的示例声明了内联数组,我不确定如何将这种类型的回调附加到我使用映射扩展自动映射的可观察数组。

简而言之,我想知道是否有人知道如何禁用先前的选择(请记住,所有选择都在一个可观察的数组中,而 SELECTED 的在另一个数组中) - 或者这是否不可能我的数据来源。因此,在图像中选择的粉红色注释中 - 我希望只显示“项目 B 和项目 C” - 但如果项目 A 可以禁用,那也可以。

我不知道 DOM 的 jQuery 操作是否可行?它必须在数据绑定之后发生,并且可能会变得混乱。

根据此处的答案 - 我的下一个屏幕有 两个 级联下拉菜单,我正在考虑应用这种独特的选择方法 - 但要组合使用。

一些代码(为保护有罪者而简化)

public class ItemsModel
{
  public List<ItemTypes> ItemTypes{ get; set; }
  public List<SelectedItemTypes> SelectedItemTypes{ get; set; }
}

public class ItemTypes
{
   public int Id { get; set; }
   public string Description { get; set; }
}

public class SelectedItemTypes
{
    public int Id { get; set; }
    public decimal Amount { get; set; }
}

**Javascript/HTML(再次剪断相关部分)**

      self.worksheetitems = ko.mapping.fromJS(@Html.Raw(Model.ToJson()))
      /* Adds an Item */
         self.addItem= function () {
                self.worksheetitems
               .SelectedItemTypes.push({ 'Id': ko.observable(), 
               'Amount': ko.observable(0)});

包含这些东西的 Html 表(注意 foreach 通过选定的项目,并绑定到所有项目数组):

    <!-- Items -->
<tbody data-bind=
      "visible: worksheetitems.SelectedItemTypes().length > 0, 
       foreach: worksheetitems.SelectedItemTypes">
          <tr>
              <td>
              <select data-bind=
                      "options: $root.worksheetitems.ItemTypes(), 
                      optionsText: 'Description', 
                      optionsValue: 'Id', value: Id"></select>
              </td>           
           <tr/>
    <!-- Snipped -->

    <button data-bind="click: $root.addItem">Add</button> 
    <!-- Add Another Item -->

【问题讨论】:

  • 很好解释的问题,但如果您在问题中添加一些代码会帮助我们制作一个最小的可重现场景。你想要的当然是可能的(没有任何 jQuery),但细节取决于你的上下文。
  • 确定我会添加一些代码
  • 我认为您可以使用指定回调for when mapping creates items 的选项来调整生成的 observable。您可以尝试将其与您提到的setOptionsDisable 后处理结合起来。这会有帮助吗?
  • @Jeroen 谢谢你的回复,让我试试

标签: knockout.js knockout-2.0 knockout-mapping-plugin knockout-mvc


【解决方案1】:

不确定我是否理解正确,但听起来您正在寻找Computed Observables

self.AvailableItemTypes = ko.computed(function() {
    var selectedTypeIds = this.SelectedItemTypes().map(function(el) {
        return el.Id; 
    });
    return this.ItemTypes().filter(function(el) {
        return selectedTypeIds.indexOf(el.Id) === -1;
    });
});

【讨论】:

  • 好吧,我认为它有效,但是在进行更多测试时,我遇到了一些奇怪的行为,我可以看到您获得了一组 selectedTypeIds,然后您正在过滤 ItemTypes - 我不确定如果该过滤器是正确的,不应该是 === 1 而不是 -1,因为您只需要未选择的 ItemTypes
  • 另外,indexOf 会返回一个数组吗?
  • indexOf 返回给定元素的索引,如果没有找到元素则返回 -1。所以过滤器应该返回一个新数组,其中只有 id 不在 selectedTypeIds 中的元素
猜你喜欢
  • 1970-01-01
  • 2015-11-28
  • 2015-03-22
  • 1970-01-01
  • 1970-01-01
  • 2011-01-27
  • 2023-04-02
  • 2016-09-13
  • 1970-01-01
相关资源
最近更新 更多