How to bind knockout checkbox to a material design lite?

≡放荡痞女 提交于 2019-12-13 12:37:44

问题


I am having problems in bind a Knockout array with Material Design Lite checkbox. Basically it doesn't show the checkbox checked.

How can that be fixed?

var ViewModel = function() {
  this.uniqueTabsNames = ko.observableArray(['one', 'two', 'three']);
}

ko.applyBindings(new ViewModel());
<link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&amp;lang=en" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/material-design-lite/1.3.0/material.css" rel="stylesheet" />
<script src="https://cdnjs.cloudflare.com/ajax/libs/material-design-lite/1.3.0/material.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>


<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
  <main class="mdl-layout__content">
    <div class="page-content">

      <p><b>generated via KO, it doesn't work</b></p>

      <!-- ko foreach: uniqueTabsNames -->
      <div class="nav-checkbox-item">
        <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" data-bind="attr: {'for': $data}">
          <input data-bind="attr: {'id': $data}" type="checkbox"  class="mdl-checkbox__input"/>
          <span class="mdl-checkbox__label" data-bind="text: $data"></span>
        </label>
      </div>
      <!-- /ko -->

      <p><b>non KO checkbox</b></p>

      <div class="nav-checkbox-item">
        <label class="mdl-checkbox mdl-js-checkbox mdl-js-ripple-effect" for='testbox'>
          <input id='testbox' type="checkbox" class="mdl-checkbox__input" />
          <span class="mdl-checkbox__label">test box</span>
        </label>
      </div>

    </div>
  </main>
</div>

回答1:


The problem here is that material design runs a function on page load to bind event handlers and functionality to certain DOM elements (like the checkbox in your case).

Because knockout essentially needs to run (or will redraw when dependencies change) the elements you bind functionality to. In your case, the foreach can/will only run after knockout has been intialized, which is typically done on DOM ready. Hence, Material won't have had access to that element when it runs it's bindings initially.

You need to have a Custom Binding to run the Material "logic" on the readiness of the element. The process is dead simple.

Pseudo-code:

  1. Create a custom binding called whatever you'd like.
  2. In the custom binding init method, pass the element knockout gives you into the Material function that will attach the required event handlers.

Hopefully that helps you!

EDIT: From the Material Design lite webpage

Material Design Lite will automatically register and render all elements marked with MDL classes upon page load. However in the case where you are creating DOM elements dynamically you need to register new elements using the upgradeElement function.

Knowing this, in your Custom Binding you need to pass the element knockout gives you, to the aforementioned handler, like: componentHandler.upgradeElement(element)

EDIT EDIT: The code

ko.bindingHandlers.SomeBinding = {
    init: function(element) {
        if(!(typeof(componentHandler) == 'undefined')){
            componentHandler.upgradeElement(element);
        }
    }
};


来源:https://stackoverflow.com/questions/44208015/how-to-bind-knockout-checkbox-to-a-material-design-lite

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!