Knockout Foreach在更改订单时重复

时间:2015-08-27 04:02:08

标签: javascript knockout.js

这是我的HTML的伪代码

foreach: thing
 ifnot: thing.disabled
  <div>Enabled</div>
  put enabled thing.stuff here
  //this is a ko.observable(bool), and moves "this"thing to the other div
  click: thing.toggleDisabled()


foreach: thing
 if: thing.disabled
  <div>Disabled</div>
  put disabled thing.stuff here
  //this is a ko.observable(bool), and moves "this"thing to the other div
  click: thing.toggleDisabled()

我有一个来自API的大型嵌套对象。我两次对这个物体进行预约。第一次,我检查一下属性是否为假。如果是,则启用它。把它放在顶部div中。如果为true,则禁用该对象,将其放在底部div中。

            <!--ko foreach: {data: $root.list.listObj.rows, as: 'row'}-->
            <!--ko ifnot: row.disabled-->
            <div class="row single-row  list-group-item">
                <div class="col-md-6">
                    <p data-bind="text: row.rule"></p>
                </div>

                <div class="col-md-6">
                    <span data-bind="click: function(){$root.list.enableCriteria(row)}">Disable</span>
                </div>

            </div>
            <!--/ko-->
            <!--/ko-->

  self.enableCriteria = function (row) {

       row.disabled(!row.disabled());
    };

你看到的功能只是简单地切换&#34;禁用&#34;属性。所有这一切都很好。

问题在于:我的界面使用点击并拖动&#34;可排序&#34;样式功能,允许用户单击并拖动以重新排列这些元素的顺序。 Knockout创造了元素&#34; foreach&#34;被迭代的每个对象都绑定到。当一个元素被拖动到另一个元素的上方或下方时,它被添加到&#34; foreach元素&#34;对于一个对象,但现在有两个对象。当值从true切换为false时,因为现在在一个&#34; foreach元素中存在两个对象&#34;顶部元素保留,而它的副本向下移动到另一个div,基本上复制它。

这是Chrome浏览器工具中呈现的 html的一部分。

<!--ko foreach: {data: $root.list.listObj.rows, as: 'row'}-->
            <!--ko ifnot: row.disabled-->
            <div class="row single-row  list-group-item">
                <div class="col-md-6">
                    <p data-bind="text: row.rule">Phone:</p>
                </div>

                <div class="col-md-6">
                    <span data-bind="click: $root.list.enableCriteria(row)">Disable</span>
                </div>

            </div>
            <!--/ko-->

            <!--ko ifnot: row.disabled-->
            <div class="row single-row  list-group-item">
                <div class="col-md-6">
                    <p data-bind="text: row.rule"> Address:</p>
                </div>

                <div class="col-md-6">
                    <span data-bind="click: $root.list.enableCriteria(row)">Disable</span>
                </div>

            </div>
            <!--/ko-->

这里是一个.col-md-6 div被移动之后的样子(注意其中一个循环注释没有内容,另一个有两个元素):

<!--ko foreach: {data: $root.list.listObj.rows, as: 'row'}-->
            <!--ko ifnot: row.disabled-->
            <!--/ko-->

            <!--ko ifnot: row.disabled-->
            <div class="row single-row  list-group-item">
                <div class="col-md-6">
                    <p data-bind="text: row.rule"> Address:</p>
                </div>

                <div class="col-md-6">
                    <span data-bind="click: $root.list.enableCriteria(row)">Disable</span>
                </div>

            </div>
            <div class="row single-row  list-group-item">
                <div class="col-md-6">
                    <p data-bind="text: row.rule">Phone:</p>
                </div>

            <!--/ko-->

电话现已移至地址以下,但它在另一部分内。当我现在切换值时,它将在另一个&#34;禁用&#34;中创建一个新元素。或&#34;启用&#34;格。

问题:有没有办法让循环元素/组件/ whatevers与该元素中的div相关联,以便与我的sortable一起使用?有没有可观察的工作来使这项工作更好?解决方案是什么?

使用元素作为foreach而不是注释会破坏我的可排序性。有什么帮助吗?

1 个答案:

答案 0 :(得分:0)

直到凌晨1点才开始工作(我发布这个之后又过了4个小时),今天早上2个小时,我想出了一个漂亮的工作。

在KO中,如果使用带注释的if或ifnot语句,则只有当observable位于if或ifnot注释内时才会对其进行评估,即使这样,只有在它所属的if或ifnot注释中才会进行评估。循环正常,但将if语句放在div元素上意味着div正在被洗牌和重新排列,因此永远不会有任何重复。

外卖,如果您需要进行任何类型的dom shuffling或重新排列,请将if和ifnot设置为实际元素而不是注释语法。

感谢您的建议!