【问题标题】:Knockout select dropdown disable item淘汰赛选择下拉禁用项目
【发布时间】:2023-03-08 17:27:02
【问题描述】:

目前我只能在淘汰赛中使用启用绑定来启用/禁用整个下拉菜单。 当 Enable = false 时,整个下拉菜单不再是可点击的,并且用户无法在下拉菜单中看到其他可能的值。

<select data-bind="options: OptionsList, optionsText: 'Key', optionsValue: 'Value', value: FieldValue, enable: Enable"></select>

渲染的是这样的:

<select disabled=""></select>

我希望做的是渲染这样的东西

<select> 
<option disabled="disabled" value='1'>One </option> 
<option selected="select"   value='2'>Two </option> 
<option disabled="disabled" value='3'>Three </option>   
</select>

这样我仍然可以看到我的选项,但它们都被禁用了,因此用户无法更改它们。

我查看了淘汰赛中的 optionsAfterRender,但我不再有权访问所选值。传入的 item 只是 select item 的 key 和 value,而不是 observable。

任何帮助将不胜感激。谢谢

【问题讨论】:

    标签: jquery knockout.js


    【解决方案1】:

    您可以选择使用foreach 构建您的option 元素,例如:

    <select data-bind="value: selected, foreach: options">
        <option data-bind="attr: { disabled: !enabled(), value: value }, text: name"></option>
    </select>
    

    示例:http://jsfiddle.net/rniemeyer/4PuxQ/

    否则,这里有一个来自 Michael Best 的 optionsBind 绑定示例,它可以让您在不使用 foreach 的情况下绑定选项(使用 optionsAfterRender 功能):

    <select data-bind="value: selected, options: options, optionsText: 'name', optionsValue: 'value', optionsBind: 'attr: { disabled: !enabled() }`"></select>'
    

    示例:http://jsfiddle.net/rniemeyer/KxY44/

    【讨论】:

    • Here 是另一种方式。需要 3.1.0
    • 完美,但 optionsBind 需要用单引号括起来:'您的代码示例以替换的斜引号结尾:`
    【解决方案2】:

    您需要使用 optionsAfterRender 将禁用应用于选项。文档中对此进行了讨论:http://knockoutjs.com/documentation/options-binding.html

    <select data-bind="options: OptionsList, optionsText: 'Key', optionsValue: 'Value', value: FieldValue, optionsAfterRender: setOptionDisable"></select>
    
    self.setOptionDisable = function(option, item) {
        ko.applyBindingsToNode(option, {disable: item.disable}, item);
    }
    

    这是它的工作演示:http://jsfiddle.net/vkFUC/

    【讨论】:

    • 很好的解决方案。谢谢。使用它时,如果您使用的是 optionsCaption 绑定,请务必处理这种情况。
    【解决方案3】:

    您可以使用 optionsAfterRender 来禁用选项。您需要为对象提供另外一个可观察的属性来启用或禁用该选项。

    代码:-

      //Optionlist will look like this 
      OptionsList: ko.observableArray([{
        Key: 1,
        Value: "Jack",
        disable: ko.observable(false)
      }, {
        Key: 2,
        Value: "Jhon",
        disable: ko.observable(false)
       }]),
    
        //Function will be used in optionsAfterRender 
        setOptionDisable: function (option, item) {
          ko.applyBindingsToNode(option, {
            disable: item.disable
          }, item);
        }
    

    Fiddle Demo

    【讨论】:

      【解决方案4】:

      对于版本 3.5.0,如果您想继续使用 mbest 解决方案(我个人认为它非常有用和优雅),只需将 ko.contextFor 替换为 chrisknoll 对这个建议的解决方法的调用:

      function contextForNodeOrNearestParent(node) {
          // Proposed fix for 3.5.0 ko.contextFor   https://github.com/knockout/knockout/pull/2447/files
          var context = ko.contextFor(node);
          if (!context && node.parentNode) {
              return contextForNodeOrNearestParent(node.parentNode);
          }
          return context;
      }
      

      来自 mbest 的原始自定义 bindingHandler 将被修改如下:

      ko.bindingHandlers.optionsBind = {
          preprocess: function (value, key, addBinding) {
              addBinding('optionsAfterRender', 'function(option, item) { ko.bindingHandlers.optionsBind.applyBindings(option, item, ' + value + ') }');
          },
          applyBindings: function (option, item, bindings) {
              if (item !== undefined) {
                  option.setAttribute('data-bind', bindings);
                  //ko.applyBindings(ko.contextFor(option).createChildContext(item), option);
                  ko.applyBindings(contextForNodeOrNearestParent(option).createChildContext(item), option);
              }
          }
      };
      

      这对我的项目很有帮助。我在这里发布这个,以防它可以节省某人的时间,并供将来个人参考。

      【讨论】:

        猜你喜欢
        • 2015-11-05
        • 1970-01-01
        • 2013-07-15
        • 2015-05-06
        • 2014-06-26
        • 1970-01-01
        • 2015-06-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多