我需要在javascript函数中获取$index
来实现值列表的上一个/下一个按钮。我发现的方法看起来很麻烦,也许有一种更简单的方法。
现在我这样做是为了在javascript中获取$ index,然后把它放在一个observable中:
<div data-bind="foreach: myarray">
<div data-bind="click: function(data, event){ onclick(data, event, $index()); }"
function onclick(idata, event, index) {
theAppViewModel.choiceindex(index);
在SO上我通过从event
获取$ index获得了一些小改进:
<div data-bind="foreach: myarray">
<div data-bind="click: onclick"
function onclick(idata, event) {
var context = ko.contextFor(event.target);
theAppViewModel.choiceindex(context.$index());
从评论者那里得到了通过在数组中搜索所选值来获取索引的方法,该方法通常具有自己的可观察值,例如: choice
:,喜欢:
var i = TheArray.indexOf(theAppViewModel.choice());
通常,页面上数组的长度不是很大,如果它有大对象,你可以使用有趣的语法搜索其中一个字段:
myarray.find(x => x.id === searchvalue);
但我想知道是否更不可能直接访问$ index而不存储在我自己的observable choiceindex
中,因为Knockout文档说$ index已经是一个可观察的。
以下是一个完整的示例代码:
<!DOCTYPE html>
<html>
<head>
<title>Test Knockout Foreach</title>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<script src='https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.1/knockout-min.js'></script>
<style>
.selected {background-color: #f0f0f0;}
</style>
</head>
<body>
<div data-bind="foreach: myarray" style="width: 10em;">
<div data-bind="click: function(data, event){ onclick(data, event, $index()); },
css: { selected: $data == $root.choice() }">
<span data-bind="text: $index"></span>
<span data-bind="text: $data"></span>
</div>
</div>
<input type="button" value="Prev" data-bind="click: onprev" />
<input type="button" value="Next" data-bind="click: onnext" />
<p>
Choice:
<span data-bind="text: choice"></span>
</p>
<p>
Index:
<span data-bind="text: choiceindex"></span>
</p>
<script>
var TheArray = ["apple", "pear", "banana", "coconut", "peanut"];
function onclick(idata, event, index) {
theAppViewModel.choice(idata);
theAppViewModel.choiceindex(index);
//var context = ko.contextFor(event.target);
//theAppViewModel.choiceindex(context.$index());
//theAppViewModel.choiceindex(index);
}
function onprev(idata, event) {
var i = theAppViewModel.choiceindex() - 1;
if (i >= 0) {
theAppViewModel.choice(TheArray[i]);
theAppViewModel.choiceindex(i);
}
}
function onnext(idata, event) {
//var i = theAppViewModel.choiceindex() + 1;
//var dummydata = theAppViewModel.choice();
//var dummy = TheArray.indexOf(dummydata);
var i = TheArray.indexOf(theAppViewModel.choice()) + 1;
if (i < TheArray.length) {
theAppViewModel.choice(TheArray[i]);
theAppViewModel.choiceindex(i);
}
}
function AppViewModel() {
var self = this;
self.myarray = ko.observableArray(TheArray);
self.choice = ko.observable();
self.choiceindex = ko.observable();
}
var theAppViewModel = new AppViewModel();
window.onload = function () {
ko.applyBindings(theAppViewModel);
}
</script>
</body>
</html>
答案 0 :(得分:1)
没有内置绑定来设置绑定中的viewmodel值,但是创建一个这样做很简单:
ko.bindingHandlers.copyIndex = {
init: function (element, valueAccessor, allBindings, vm, bindingContext) {
vm.index = bindingContext.index;
}
};
使用方法如下:
<div data-bind="foreach: myarray">
<div data-bind="copyIndex"></div>
</div>
但是,我仍然不推荐这种方法,因为它将viewmodel行为与特定绑定的存在联系起来。 Jason Spake建议使用myarray.indexOf($data)
(或ko.utils.arrayIndexOf(myarray, $data)
)会更加强大。
答案 1 :(得分:-1)
在html部分写'index'而不是'index()'。 试试这个:
<div data-bind="foreach: myarray" style="width: 10em;">
<div data-bind="click: function(data, event){ onclick(data, event, $index},
css: { selected: $data == $root.choice() }">
<span data-bind="text: $index"></span>
<span data-bind="text: $data"></span>
</div>
</div>