从Knockout.js选项数组中删除后重新初始化Materialize.css选择框

gzo*_*ost 7 javascript materialize knockout.js

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

这对于初始显示选择框是正常的,并且当选项被添加到Knockout.js'选项'observableArray时,使用'optionsAfterRender'绑定到(重新)初始化后添加每个选项(浪费,但有效) .

删除选项时,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>
Run Code Online (Sandbox Code Playgroud)

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

Jer*_*oen 8

甲自定义绑定处理程序是更适合于集成的自定义用户界面组件等material_select与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());
Run Code Online (Sandbox Code Playgroud)
<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>
Run Code Online (Sandbox Code Playgroud)

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

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

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.
  }
};
Run Code Online (Sandbox Code Playgroud)