[英]Moving item down in ko.observableArray model binding issue
Edit 编辑
Apparently the logic is correct. 显然,逻辑是正确的。 I suspect the issue is with how I'm binding my View Model from the JSON response of our API. 我怀疑问题出在我如何从API的JSON响应中绑定视图模型。 I've added more code to try and help diagnose the issue. 我添加了更多代码以尝试帮助诊断问题。
Am I binding the view model correctly? 我是否正确绑定了视图模型?
Original post 原始帖子
I'm not asking how to move items around in an observableArray, I got my code to move items up and down inside an array from here: How do I swap two items in an observableArray? 我不是在问如何在observableArray中移动项目,我得到了从此处在数组内上下移动项目的代码: 如何在observableArray中交换两个项目?
Moving up by @Michael Best: https://stackoverflow.com/a/10630319/1888402 由@Michael Best上移: https ://stackoverflow.com/a/10630319/1888402
Moving down by @Moes: https://stackoverflow.com/a/26726556/1888402 由@Moes向下移动: https ://stackoverflow.com/a/26726556/1888402
The problem I'm having is moving the item down. 我遇到的问题是将物品下移。 It moves up just fine, the issue seems to be with the logic. 它上升得很好,问题似乎出在逻辑上。
JSON Model JSON模型
{
"Options": {
"SelectedHeader": "Left Header",
"AvailableHeader": "Right Header"
},
"Selected": [
{
"Order": 2,
"ID": 1,
"Label": "Duration"
},
{
"Order": 11,
"ID": 5,
"Label": "Metres / Min"
},
{
"Order": 23,
"ID": 7,
"Label": "Sprint Dis/Min"
},
{
"Order": 9,
"ID": 15,
"Label": "Max Velocity"
},
{
"Order": 6,
"ID": 16,
"Label": "Hi Intensity Running"
}
],
"Available": [
{
"ID": 123,
"Label": "I'm Available"
}
],
"WebServiceMethodUrl": "../../../Services/SomeAsmxService.asmx/SaveStuff"
}
View Model 查看模型
function ViewModel(){
var self = this;
self.Options = model.Options
self.Available = ko.observableArray(model.Available);
self.Selected = ko.observableArray(model.Selected);
self.WebServiceMethodUrl = model.WebServiceMethodUrl;
self.addSelected = function(item){
item.Order = self.Selected().length;
self.Available.remove(item);
self.Selected.push(item);
};
self.removeSelected = function(item){
self.Available.push(item);
self.Selected.remove(item);
};
self.moveUp = function(item) {
var i = self.Selected.indexOf(item);
if (i >= 1) {
var array = self.Selected();
self.Selected().splice(i-1, 2, array[i], array[i-1]); //Works fine
item.Order = i;
}
};
self.moveDown = function(item) {
var i = self.Selected.indexOf(item);
if (i < self.Selected().length - 1) {
var array = self.Selected();
self.Selected().splice(i, 2, array[i + 1], array[i]);
item.Order = i;
self.Selected.valueHasMutated(); //Force rebind
}
};
self.SaveIt = function(){
postDataAsync(self.WebServiceMethodUrl, "{queryString: '"+ ko.toJSON(self) + "'}", "Could not save settings.", function (resp){});
}
self.sortedSelected = ko.computed(function(){
return self.Selected().sort(function(left, right) { return left.Order == right.Order ? 0 : (left.Order < right.Order ? -1 : 1) });
});
}
var vm = new ViewModel();
ko.applyBindings(ViewModel);
HTML & Bindings HTML和绑定
<!-- ko if: sortedSelected().length -->
<tbody data-bind="with:sortedSelected">
<!-- ko foreach: Selected -->
<!-- ko ifnot: (ID == 0) -->
<tr>
<td class="order">
<p data-bind="click: moveUp, clickBubble: false"><i class="fa fa-arrow-up"></i></p>
<p data-bind="text: $index() + 1"></p>
<p data-bind="click: moveDown, clickBubble: false"><i class="fa fa-arrow-down move-down"></i></p>
</td>
<td data-bind="text:Label, attr: { id: ID }"></td>
<td><a class="remove" data-bind="click: removeSelected, clickBubble: false">Remove <i class="fa fa-arrow-circle-o-right"></i></a></td>
</tr>
<!-- /ko-->
<!-- /ko-->
</tbody>
<!-- /ko -->
So if I was to call the moveDown function on item 5, it should then become item 6 and item 6 should become item 5. Not sure why this isn't working since it's just the logic being inverted. 因此,如果我要在第5项上调用moveDown函数,则它应该变成第6项,而第6项应该变成第5项。不确定这为什么不起作用,因为这只是倒置的逻辑。
Example 例
The problem is with your sortedSeleted
computed. 问题出在您的sortedSeleted
计算中。 Any time Selected
is modified, the computed will be reevaluated because it has a dependency on Selected
. 每当修改Selected
,都会重新评估计算值,因为它依赖于Selected
。 When the computed is evaluated it sorts Selected
. 对计算所得的值进行评估时,将对Selected
进行排序。 You may have not realized that sort
modifies the array it is called on while also returning the array. 您可能没有意识到sort
会修改它调用的数组,同时还返回该数组。 This sorting by Order
is what's making the moveUp
and moveDown
functions appear inconsistent. 这种按Order
排序的原因是使moveUp
和moveDown
函数看起来不一致。
You most likely want to sort a copy of Selected
. 您最有可能想要对Selected
的副本进行排序。 As @RoyJ pointed out, you can use slice
to get a shallow copy of an array. 正如@RoyJ指出的那样,您可以使用slice
来获取数组的浅表副本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.