我有一个可观察的项目数组。 '项目的一个属性'是' position',表示项目在列表中的位置。我希望能够通过下拉每个项目旁边的位置来重新排序页面上的项目。当用户在下拉列表中选择项目的位置时,将重新计算受影响的任何项目的位置值。
我遇到的问题是当我尝试使用事件绑定进行下拉时 - 我无法找到一种方法来传递原始&我的重新定位的新职位'功能。
我确信这可以通过使用这个简单示例的数组索引来完成,但我试图看看是否可以避免这种情况。
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);
答案 0 :(得分:0)
您想要访问旧位置,但您尚未为其定义任何存储空间。每个项目都必须有一个oldPosition变量(我已经成为私有变量),并且在更新oldPosition之前调用position
函数的reposition
订阅。
我已经对您的设计进行了一些重新设计,我认为这有点令人费解。我还没有实施reposition
,我想你想要转移其他项目&#39;这些职位不会有重复。
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);
&#13;
<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>
&#13;