【发布时间】:2015-10-09 02:23:07
【问题描述】:
编辑
显然逻辑是正确的。我怀疑问题在于我如何从我们 API 的 JSON 响应中绑定我的视图模型。我添加了更多代码来尝试帮助诊断问题。
我是否正确绑定了视图模型?
原帖
我不是在问如何在 observableArray 中移动项目,我的代码是从这里在数组中上下移动项目: How do I swap two items in an observableArray?
@Michael Best 向上移动:https://stackoverflow.com/a/10630319/1888402
@Moes 下移:https://stackoverflow.com/a/26726556/1888402
我遇到的问题是将项目向下移动。它移动得很好,问题似乎与逻辑有关。
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"
}
查看模型
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 和绑定
<!-- 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 -->
因此,如果我要在第 5 项上调用 moveDown 函数,那么它应该成为第 6 项,第 6 项应该成为第 5 项。不知道为什么这不起作用,因为它只是逻辑被反转了。
示例
【问题讨论】:
-
它对我有用。此外,如果您在可观察数组而不是后备数组上调用 splice,则无需调用
valueHasMutated。此外,如果在数组中的最后一个索引上使用,这将无法正常工作。将您的支票更改为i < self.Selected().length - 1。 -
有趣,我将不得不发布更多我的代码。
-
您没有使用 Knockout 的
splice。在 observableArray 上调用它,而不是在内容上。 -
请做一个小提琴来告诉我们什么是行不通的。
-
一旦你解决了这个问题,你会注意到你的绑定的所有上下文问题。例如,您不能在
with: sortedSelected中包含foreach: Selected,因为 sortedSelected 没有名为“Selected”的属性。
标签: javascript arrays knockout.js