【问题标题】:Re-init Materialize.css select box after removal from Knockout.js options array从 Knockout.js 选项数组中删除后重新初始化 Materialize.css 选择框
【发布时间】:2015-12-21 10:18:32
【问题描述】:

我有一个选择框,其中的选项和选择是通过 Knockout.js 处理的。我想使用 Materialize CSS 来设置它的样式。

这适用于Select框的初始显示,当添加到BocketOut.js的选项时,通过使用“OptionsAwterrender”绑定到(重新)在添加每个选项后初始化(浪费,但有效)。

删除选项时,Knockout.js 不提供类似于“optionsAfterRender”的任何内容,因此没有明显的方法来触发 Materialize CSS 魔法的重新初始化。

问题:有没有你可以看到的非疯狂选项?

代码:

<select data-bind="

      options: options,
      optionsText: function(item) { return optionsText[item] },
      value: displayedValue,

      optionsAfterRender: function (option, item) {
         setTimeout(function() {
            $(option.parentElement).material_select();
         }, 0);
      }
     ">
</select>

('setTimeout' 是必需的,否则不会选择所选选项。)

【问题讨论】:

    标签: javascript knockout.js materialize


    【解决方案1】:

    custom binding handler 更适合将 material_select 等自定义 UI 组件与 KnockoutJS 集成。这是构建此类处理程序的一种方法:

    ko.bindingHandlers["materializeSelect"] = {
      after: ['options'],
      init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        // Initial initialization:
        $(element).material_select();
        
        // Find the "options" sub-binding:
        var boundValue = valueAccessor();
        
        // Register a callback for when "options" changes:
        boundValue.options.subscribe(function() {
          $(element).material_select();
        });
      },
      update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        
      }
    };
    
    function RootViewModel() {
      var self = this, i = 2;
      self.options = ko.observableArray([{id: 1, txt: "Option A"}, {id: 2, txt: "Option two"}]);
      self.selectedOption = ko.observable(null);
      
      // For testing purposes:
      self.addOption = function() { self.options.push({id: ++i, txt: "Dynamic option " + i}); };
    }
    
    ko.applyBindings(new RootViewModel());
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.4/js/materialize.min.js"></script>
    <link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.4/css/materialize.min.css" rel="stylesheet"/>
    
    <select data-bind="materializeSelect: { options: options },
                       options: options,
                       optionsText: 'txt',
                       value: selectedOption">
    </select>
    
    <button data-bind="click: addOption">Add option dynamically</button>

    说实话,我觉得这是一个问题/遗漏,甚至可能是 MaterializeCSS 中的一个错误,它显然没有注意到 select 选项的变化。像 Select2 和 Chosen do 这样的 IIRC 库具有此功能。

    无论如何,如果 MaterializeCSS 正确地注意到动态添加的选项,我仍然会使用自定义绑定处理程序,只是一个更简单的处理程序:

    ko.bindingHandlers["materializeSelect"] = {
      after: ['options'],
      init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        $(element).material_select();
      },
      update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        // Handle ViewModel changes of which MaterializeCSS needs custom
        // notification here.
      }
    };
    

    【讨论】:

    • 我通常会在 reinit 之前致电.material_select('destroy'); 以确保安全。 materializecss 有点年轻恕我直言
    • 感谢完美的回答 - 这也解决了我遇到的下一个问题,如何在 KO 模型中的值更改后重新初始化!
    【解决方案2】:

    Jeroen 的回答很好也很正确,我想使用 SO cmets 添加一个附录,但我认为使用完整格式会更好。

    Materialize 在选择时响应 disable 绑定似乎有点奇怪,特别是如果该禁用依赖于另一个淘汰赛 observable 的更新(通常是这样)。

    我在更新函数中使用以下内容:

    if(allBindings().disable != undefined && allBindings().disable == true){
       $(element).prop("disabled", true);
    }
    else{
       $(element).prop("disabled", false);     
    }
    
    $(element).material_select();
    

    我最初尝试只在更新函数中调用$(element).material_select(),但它似乎有点虚伪,只是在某些时候有效。显式更改元素上的 disabled 属性似乎每次都有效。

    可能有一种更简洁的方法可以做到这一点,但希望这个示例能够说明这一点:根据绑定的状态显式设置 disabled 属性。

    我不知道使用其他绑定是否会遇到类似的问题,visible 等,但如果是的话,这些问题可能会以类似的方式解决。

    【讨论】:

      猜你喜欢
      • 2019-02-18
      • 1970-01-01
      • 2015-03-22
      • 1970-01-01
      • 2020-01-30
      • 2012-07-12
      • 2019-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多