【问题标题】:Using knockoutjs data-bind on nested ul在嵌套的 ul 上使用 knockoutjs 数据绑定
【发布时间】:2015-11-15 18:51:03
【问题描述】:

我尝试在按钮上使用 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>

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

【问题讨论】:

  • 我尝试设置一个示例,但无法理解错误。你能不能解释一下:jsfiddle.net/Salmin/ez7bfmg9
  • 您还需要 zurb 基础库,所以这个例子可以工作。问题是单击每个按钮都可以正常工作,但单击向下箭头并随后删除,始终删除最后一项而不是单击的那个。
  • 在尝试重现您的小提琴上的问题失败后,我注意到该问题仅出现在基础库中。
  • 这是一个演示问题的小提琴:jsfiddle.net/6d5jnL3r

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


【解决方案1】:

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

为了使 DOM 项目在 Foundation 初始化时及时出现,我将 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>

【讨论】:

  • 谢谢!完美运行!
【解决方案2】:

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

var lastClicked;

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

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

小提琴here.

【讨论】:

  • 首先感谢您的回复,但我写这篇文章是为了了解内部 ul 与数据绑定之间的问题。我已经有了解决方法,但我想要的是了解库之间集成的问题。谢谢!
  • 问题是小部件在按钮之间共享菜单。
  • 我试图通过将人名绑定到菜单的 id(嵌套的 ul)+ span 的 data-dropdown 属性来解决这个问题,但由于某种原因它不起作用...
猜你喜欢
  • 2012-02-23
  • 2017-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-07
  • 1970-01-01
相关资源
最近更新 更多