当我尝试在由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>
答案 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>
希望有所帮助。