繁体   English   中英

使用淘汰赛JS重新排序列表中的项目

[英]Reorder items in a list using Knockout JS

我有一系列可观察的物品。 “项目”的属性之一是“位置”,它表示项目在列表中的位置。 我希望能够通过在每个项目旁边放置一个带有下拉菜单的位置来对页面上的项目进行重新排序。 当用户在下拉菜单中选择项目的位置时,将重新计算所有受影响项目的位置值。

我遇到的问题是,当我尝试利用事件绑定进行下拉菜单时-我想不出一种将原始和新职位传递给我的“重新定位”功能的方法。

我敢肯定,可以通过在此简单示例中使用数组索引来完成此操作,但是我正在尝试查看是否可以避免这种情况。

JSFiddle: http : //jsfiddle.net/4tqahpkg/3/

<div class='liveExample'>
<ul data-bind="foreach: orderedItems">
    <li>
        <div>   <span data-bind="text: name"> </span> has Position:
            <select id="pos" data-bind=" options: orderedItems,
                    optionsText: function(item) { return item.position   },
                    optionsValue: function(item){ return item.position   },
                    value: position,
                    event: { change: function () {reposition($data.name(), position()); } } "></select>
        </div>
    </li>
</ul>

var Item = function (name, position) {
    this.name = ko.observable(name);
    this.position = ko.observable(position);

}

var viewModel = function () {
    var self = this;

    this.items = [
    new Item("item Three", "3"),
    new Item("item One", "1"),
    new Item("item Two", "2"),
    new Item("item Five", "5"),
    new Item("item Four", "4"),
    new Item("item Six", "6")];


    self.orderedItems = ko.computed(function () {

        return ko.utils.arrayFilter(this.items, function (item) {
            return true;
        }).sort(function (a, b) {
            var value1 = "",
                value2 = "";
            value1 = a.position() ? a.position() : "";
            value2 = b.position() ? b.position() : "";
            return value1 == value2 ? 0 : (value1 < value2 ? -1 : 1);
        });
    });

    self.curName = ko.observable();

    self.curItem = ko.computed(function (name) {
        return ko.utils.arrayFilter(this.items, function (item) {
            return item.name() == self.curName();
        });
    });

    self.reposition = function (name, newPosition) {

        self.curName(name);
        origPosition = self.curItem()[0].position();

        if (origPosition < newPosition) {
            for (var x = 0; x < orderedItems.length; x++) {
                if (origPosition < newPosition && self.orderedItems()[x].position() >= origPosition && self.orderedItems()[x].position() < newPosition) {
                    self.orderedItems()[x].position(self.orderedItems()[x].position() - 1);
                }

                if (origPosition > newPosition && self.orderedItems()[x].position() >= newPosition && self.orderedItems()[x].position() < origPosition) {
                    self.orderedItems()[x].position(self.orderedItems()[x].position() + 1);
                }

                if (self.orderedItems().name() == name) {
                    self.orderedItems()[x].position(newPosition);
                }
            }
        }
    };


};

ko.applyBindings(viewModel);

您想访问旧职位,但尚未为其定义任何存储。 每个项目都必须有一个oldPosition变量(我已将其设为私有变量),并且必须有一个在position上的订阅,以便在更新oldPosition之前调用您的重reposition函数。

我对您的设计进行了一些重新架构,我认为这有点令人费解。 我还没有实现reposition ,我想您想转移其他项目的位置,以便您没有重复。

 var viewModel = function() { var self = this; var Item = function(name, pos) { this.name = ko.observable(name); this.position = ko.observable(pos); var oldPosition = pos; this.position.subscribe(function(newValue) { self.reposition(this, oldPosition, newValue); oldPosition = newValue; }, this); }; this.items = [ new Item("item Three", "3"), new Item("item One", "1"), new Item("item Two", "2"), new Item("item Five", "5"), new Item("item Four", "4"), new Item("item Six", "6") ]; self.orderedItems = ko.computed(function() { return ko.utils.arrayFilter(this.items, function(item) { return true; }).sort(function(a, b) { return a.position() - b.position(); }); }); self.curName = ko.observable(); self.reposition = function(item, oldPosition, newPosition) { console.debug("Reposition", item, oldPosition, newPosition); }; }; ko.applyBindings(viewModel); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> <div class='liveExample'> <ul data-bind="foreach: orderedItems"> <li> <div> <span data-bind="text: name"> </span> has Position: <select id="pos" data-bind=" options: orderedItems, optionsText: 'position', optionsValue: 'position', value: position "></select> </div> </li> </ul> </div> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM