【问题标题】:knockout dropdown淘汰赛下拉菜单
【发布时间】:2017-03-27 15:09:54
【问题描述】:

我在获取绑定下拉列表中的选定项目时遇到问题。

<p>
  Your Group: 
  <select data-bind="options: availableGroups, optionsText: 'Name', optionsValue: 'GroupId', value: selectedGroup, optionsCaption: 'Choose...'"></select>
</p>
<p>
  I am visible
  You have chosen <span data-bind="text: selectedGroup() ? selectedGroup().Name : 'Nothing'"></span>
</p>

当我从下拉列表中选择某些内容时,我想获取选择的文本,而不是值。我对淘汰赛很陌生,并试图解决这个问题。我为此创建了一个小提琴。

http://jsfiddle.net/voam/FjRxn/

【问题讨论】:

  • 你为什么不只使用下拉文本值?
  • 我现在看到我正在尝试让淘汰赛构建下拉列表,其中选项值全部设置为生成标记中的 groupid 字段,这不是必需的。因此,即使未在标记中设置值,当我检索所选项目时,我也可以将 GroupId 字段作为所选组对象的一部分。

标签: knockout.js


【解决方案1】:

对于您最初的问题,@Pete 的回答是正确的,但是由于您需要将 GroupId 保留为您可以执行 this (modified fiddle) 的值。

首先将selectedGroup 属性重命名为selectedGroupId

然后基于 selectedGroupId 定义了一个新的计算 observable selectedGroup

self.selectedGroup = ko.computed(function () {
  for (var i = 0; i < groups.length; i++) {
    if (groups[i].GroupId == self.selectedGroupId())
      return groups[i];
  }
  return null;
});

还定义了var self = this

【讨论】:

    【解决方案2】:

    我只是想发布一个我最近一直在使用的解决方案来解决这个问题。它利用绑定处理程序(valueAppendText 和 textFromOption)并将一个可观察对象附加到由下拉列表跟踪的可观察对象。此解决方案并不完整,但演示了不使用添加计算来获取下拉文本的想法。该解决方案还使用了 jQuery,可以将其删除,但由于我在我的项目中(大部分)使用 jQuery,所以我将其保留。下面的 jsFiddle 链接演示了该功能。

    小提琴: http://jsfiddle.net/FjRxn/65/

    标记:

    <select data-bind="options: availableGroups, optionsText: 'Name', optionsValue: 'GroupId', valueAppendText: selectedGroup, optionsCaption: 'Choose...'"></select>
    
    <p>
        I am visible
        You have chosen <span data-bind="textFromOption: selectedGroup"></span>
        <div>
            Group Id: <span data-bind="text: selectedGroup"></span>
        </div>
    </p>
    

    绑定处理程序:

    ko.bindingHandlers.valueAppendText = {
        init: function(element, valueAccessor, allBindingsAccessor, context) {
          var $element, newValueAccessor, observable, setText;
    
          observable = valueAccessor();
          observable.selectedOptionText = ko.observable(null);
          newValueAccessor = function() {
            return observable;
          };
          $element = $(element);
          setText = function() {
            return observable.selectedOptionText($element.find("option:selected").text());
          };
          setTimeout(setText, 5);
          $element.change(function() {
            return setText();
          });
          return ko.bindingHandlers.value.init(element, newValueAccessor, allBindingsAccessor, context);
        },
        update: function(element, valueAccessor, allBindingsAccessor, context) {
          return ko.bindingHandlers.value.update(element, valueAccessor, allBindingsAccessor, context);
        }
      };
    
      ko.bindingHandlers.textFromOption = {
        update: function(element, valueAccessor, allBindingsAccessor, context) {
          var newValueAccessor, observable;
    
          observable = valueAccessor();
          newValueAccessor = function() {
            if (ko.isObservable(observable.selectedOptionText)) {
              return observable.selectedOptionText();
            }
            return observable();
          };
          return ko.bindingHandlers.text.update(element, newValueAccessor, allBindingsAccessor, context);
        }
      };
    

    【讨论】:

      【解决方案3】:

      改变

      <select data-bind="options: availableGroups, optionsText: 'Name', optionsValue: 'GroupId', value: selectedGroup, optionsCaption: 'Choose...'"></select>
      

      收件人:

      <select data-bind="options: availableGroups, optionsText: 'Name', value: selectedGroup, optionsCaption: 'Choose...'"></select>
      

      【讨论】:

      • 不过,我还需要将 GroupId 保留为选项的值字段。
      【解决方案4】:

      您还可以在可观察的 selectedGroup 上使用订阅功能。我还创建了另一个 observable 作为“selectedGroupId”。

      在订阅事件中,我将 GroupId 的值分配给新的 observable "selectedGroupId"

       self.selectedGroup.subscribe(function(item)
           {
                debugger;
                self.selectedGroupId(item.GroupId);
                return item.Name;
            });
      

      请查看更新的 Fiddle here

      【讨论】:

        【解决方案5】:

        最简单的解决方案是从元素中删除 optionsValue 绑定。然后它将整个对象存储在可观察对象中,您可以访问所有属性。

        jsfiddle

        <select data-bind="options: availableGroups, optionsText: 'Name',
        value: selectedGroup, optionsCaption: 'Choose...'"></select>
        

        【讨论】:

          【解决方案6】:

          我个人会使用@pomber 的答案,稍作修改。

          self.selectedGroup = ko.computed(function(){
            return ko.utils.arrayFirst(self.availableGroups(), function(grp) {
              return grp.GroupId == self.selectedGroupId();
            }
          }, this);
          

          我不喜欢在计算的 observables 中使用 for 循环。

          Fiddle

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2016-06-09
            • 1970-01-01
            • 2015-05-06
            • 1970-01-01
            • 2018-08-09
            • 1970-01-01
            • 2014-09-26
            • 2015-06-11
            相关资源
            最近更新 更多