knockoutjs和materializecss javascript下拉列表

时间:2016-05-05 18:04:56

标签: knockout.js materialize

当我尝试在由knockoutjs foreach绑定动态生成的代码中使用materializecss javascript下拉列表(http://materializecss.com/dropdown.html)时,单击下拉触发器时,下拉选项不会显示。

<ul class="list" data-bind="foreach: items">
  <li>
    <!-- Dropdown Trigger -->
    <a class='dropdown-button btn' href='#' 
             data-bind="attr: {'data-activates': 'dropdown' + $index()}">Drop Me!</a>
    <!-- Dropdown Structure -->
    <ul data-bind="attr: {id: 'dropdown' + $index()}" class='dropdown-content'>
      <li><a href="#!">one</a></li>
      <li><a href="#!">two</a></li>
      <li><a href="#!">three</a></li>
    </ul>
  </li>
</ul>

Materialisecss表示必须使用

初始化下拉列表
$(".dropdown-button").dropdown();

但是,这似乎没有效果。

任何帮助将不胜感激。我无法在knockoutjs论坛或其他地方找到帮助。

编辑 - 完整的工作模式

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <!--Import Google Icon Font-->
    <link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.6/css/materialize.min.css">
</head>
<body>
    <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.6/js/materialize.min.js"></script>

    <script  >
        function ItemsViewModel() {
            var that = this;

            function collectionItem(root, title) {
                var self = this;
                self.title = ko.observable(title);
            };

            that.items = ko.observableArray();
            that.loadItems = function () {
                for (var i = 0, j = 5; i < j; i++) {
                   that.items.push(new collectionItem(that,"title"+ i.toString()));
                }
            };
        };

        ko.bindingHandlers.materializeDropdown = {
            init: function (element, valueAccessor) {
                $(element).dropdown();
            },
            update: function (element, valueAccessor, allBindings) {
            }
        };

        var itemsViewModel;

        $(document).ready(function () {
            itemsViewModel = new ItemsViewModel();

            ko.applyBindings(itemsViewModel,      $("#divForItemsViewModel").get(0));
            itemsViewModel.loadItems();
        });
    </script>
    <div id="divForItemsViewModel">
         <ul class="list" data-bind="foreach: items">
            <li>
                <div data-bind="text:title"></div>
                <!-- Dropdown Trigger -->
                <a class='dropdown-button btn' href='#'
                   data-bind="attr: {'data-activates': 'dropdown' + $index()}, materializeDropdown">Drop Me!</a>
                <!-- Dropdown Structure -->
                <ul data-bind="attr: {id: 'dropdown' + $index()}" class='dropdown-content'>
                    <li><a href="#!">one</a></li>
                    <li><a href="#!">two</a></li>
                    <li><a href="#!">three</a></li>
                </ul>
            </li>
        </ul>
        <a class='dropdown-button btn' href='#'
       data-activates="dropdownx">Drop Me THIS WORKS</a>
        <ul id="dropdownx" class='dropdown-content'>
            <li><a href="#!">one</a></li>
            <li><a href="#!">two</a></li>
            <li><a href="#!">three</a></li>
        </ul>
    </div>
</body>
</html>

1 个答案:

答案 0 :(得分:2)

我认为你需要的是custom binding。我认为发生的事情是,当调用$(".dropdown-button").dropdown();时,foreach绑定可能尚未执行,因此下拉列表的值尚不可用。

我会在下拉触发器的ul标记之前移动下拉结构的a,以确保结构中的任何绑定都在触发器中的绑定之前运行。然后将自定义绑定添加到触发器,调用时会在目标上执行.dropdown()

修改

以下是建议的自定义绑定示例:

ko.bindingHandlers.materializeDropdown = {
    init: function(element, valueAccessor) {
        $(element).dropdown();
    },
    update: function(element, valueAccessor, allBindings) {
    }
};

然后html可以如下。

<ul class="list" data-bind="foreach: items">
  <li>
    <!-- Dropdown Structure -->
    <ul data-bind="attr: {id: 'dropdown' + $index()}" class='dropdown-content'>
      <li><a href="#!">one</a></li>
      <li><a href="#!">two</a></li>
      <li><a href="#!">three</a></li>
    </ul>
    <!-- Dropdown Trigger -->
    <a class='dropdown-button btn' href='#' 
             data-bind="attr: {'data-activates': 'dropdown' + $index()}, materializeDropdown">Drop Me!</a>
  </li>
</ul>

希望有所帮助。