如何在javascript中访问knockout $ index

时间:2017-04-07 15:51:39

标签: javascript knockout.js

我需要在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>

2 个答案:

答案 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>