在嵌套的ul上使用knockoutjs data-bind

时间:2015-11-15 18:51:03

标签: javascript html knockout.js data-binding zurb-foundation

我尝试在按钮上使用foreach数据绑定。由于基础拆分按钮,我试图为每条记录生成的按钮都有自己的选项列表。 问题是内部ul没有访问绑定的正确项目。

我写了一个小例子程序来说明问题:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Try</title>
    <link rel="stylesheet" href="css/foundation.css" />
    <script src="js/vendor/modernizr.js"></script>
</head>
<body>
<script src="js/vendor/jquery.js"></script>
<script src="js/foundation.min.js"></script>



<h4 class="">persons</h4>
<ul data-bind="foreach: { data: persons, as: 'person' }" class="inline-list">
    <li>
        <a class="small success round button split" data-bind="click: $parent.presentPerson"><h2 data-bind="text: person.name"></h2> <span data-dropdown="drop"></span></a><br>
        <ul id="drop" class="f-dropdown" data-dropdown-content>
            <li><a data-bind="click: $parent.removePerson">Remove</a></li>
        </ul>
    </li>
</ul>

<script type='text/javascript' src='js/knockout-3.4.0rc.js'></script>
<script type="text/javascript">
    // Init foundation
    $(document).foundation();
    // This is a simple *viewmodel* - Java0Script that defines the data and behavior of your UI
    function AppViewModel() {
         var self = this;

        self.persons = ko.observableArray([
            { name: 'Bert', age: 30, hobbies :["music","computers"] },
            { name: 'Charles', age : 31, hobbies :["sports"] },
            { name: 'Denise', age: 32 , hobbies :["art", "fashion", "games"]}
        ]);


        self.removePerson = function() {
            self.persons.remove(this);
        };

        self.presentPerson = function () {
            var person = this;
            window.alert(person.name + " " + person.age);
        };
    }

    // Activates knockout.js
    ko.applyBindings(new AppViewModel());
</script>
</body>
</html>

单击按钮本身时,person对象是正确的,单击箭头并选择remove将导致始终删除最后一个对象而不是所选对象。

2 个答案:

答案 0 :(得分:0)

删除菜单项似乎在按钮之间共享,因此告诉它影响哪一个的方法是记住最后一次点击。

var lastClicked;

self.removePerson = function () {
    self.persons.remove(lastClicked);
};

self.presentPerson = function () {
    var person = this;
    window.alert(person.name + " " + person.age);
    lastClicked = person;
};

小提琴here

答案 1 :(得分:0)

为了避免在所有按钮之间共享一个菜单,您需要为它们提供唯一的ID。在Knockout中,我们通常使用$index

为了让所有DOM项目及时出现以进行基础初始化,我将foundation调用移至ko.applyBindings之后。创建一个自定义绑定处理程序可能是一个好主意,该处理程序将基础应用于更新的DOM项目或其他任何内容,但这对于此练习来说已经足够了。

// This is a simple *viewmodel* - Java0Script that defines the data and behavior of your UI
function AppViewModel() {
    var self = this;

    self.persons = ko.observableArray([{
        name: 'Bert',
        age: 30,
        hobbies: ["music", "computers"]
    }, {
        name: 'Charles',
        age: 31,
        hobbies: ["sports"]
    }, {
        name: 'Denise',
        age: 32,
        hobbies: ["art", "fashion", "games"]
    }]);


    self.removePerson = function (data) {
        console.debug("Remove", data, this);
        self.persons.remove(this);
    };

    self.presentPerson = function () {
        var person = this;
        window.alert(person.name + " " + person.age);
    };
}

// Activates knockout.js
ko.applyBindings(new AppViewModel());
// Init foundation
$(document).foundation();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/modernizr/2.8.3/modernizr.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/foundation/5.5.3/js/foundation.min.js"></script>
<link href="//cdnjs.cloudflare.com/ajax/libs/foundation/5.5.3/css/foundation.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<h4 class="">persons</h4>

<ul data-bind="foreach: { data: persons, as: 'person' }" class="inline-list">
    <li> <a class="small success round button split" data-bind="click: $parent.presentPerson"><h2 data-bind="text: person.name"></h2>
        <span data-bind="attr:{'data-dropdown': 'drop'+$index()}"></span></a>
        <ul data-bind="attr:{id: 'drop'+$index()}" class="f-dropdown" data-dropdown-content>
            <li><a data-bind="click: $parent.removePerson">Remove</a>
            </li>
        </ul>
    </li>
</ul>