如何在计算的可观察对象中使用索引 [knockout.js]

How to use index in computed observable [knockout.js]

下面是一些示例代码。我需要在计算变量中使用项目索引,但我不知道如何在不访问保存视图模型应用程序的变量的情况下执行此操作。

<template type="text/ko-template" id="rowTemplate">
    <li><span data-bind="text: number"></span> = <span data-bind="text: word"></span></li>
</template>

<ul data-bind="template: { name: 'rowTemplate', foreach: rowArray }"></ul>

<script>

    function RowModel(word) {
        var self = this;
        self.word = ko.observable(word);
        self.number = ko.computed({
            read: function(){
                return "#" + app.rowArray.indexOf(self); // This works, but is far from ideal.
            },
            deferEvaluation: true
        });

    };

    function ViewModel() {
        var self = this;
        self.rowArray = ko.observableArray([
            new RowModel('Zero'),
            new RowModel('One'),
            new RowModel('Two'),
        ]);
    };

    var app = new ViewModel();
    ko.applyBindings(app);

</script>

我已经尝试将带有注释的行更改为许多内容,例如 $indexself.index() 以及所有与 $parentContext 类似的组合,等等

您可以在视图中使用 $index 而不是使用计算,它给出了数组的当前索引。

查看:

<template type="text/ko-template" id="rowTemplate">
    <li><span data-bind="text: '#'+($index()+1)"></span> = <span data-bind="text: word"></span></li>
</template>

<ul data-bind="template: { name: 'rowTemplate', foreach: rowArray }"></ul>

viewModel:

function RowModel(word) {
    var self = this;
    self.word = ko.observable(word);
};

function ViewModel() {
    var self = this;
    self.rowArray = ko.observableArray([
        new RowModel('Zero'),
        new RowModel('One'),
        new RowModel('Two'),
    ]);
};

var app = new ViewModel();
ko.applyBindings(app);

工作样本here

我发布这个问题是为了简化我的真实 'problem',这可能不是最好的主意。我的意图是访问计算的可观察对象中的上下文,因此我提到了 $parentContext.

我的研究导致了以下堆栈溢出问题和答案,关于 'context':How can I use knockout's $parent/$root pseudovariables from inside a .computed() observable?

Knockout 确实提供了 some functions 来获取上下文,但它们在这种情况下不起作用(它们仅在事件处理程序中有用):

ko.dataFor(element) - returns the data that was available for binding against the element ko.contextFor(element) - returns the entire binding context that was available to the DOM element.

因此,最好的解决方案似乎与我原来的问题非常相似,但它显式地将 'context' 存储在模型对象上,然后用于计算的可观察对象(如上述 [ 中进一步讨论的那样) =31=].问答)

function RowModel(word, context) {
    var self = this;
    self.word = ko.observable(word);
    self.context = context; // Save the 'context' to the object.
    self.number = ko.computed({
        read: function() {
            return "#" + self.context.rowArray.indexOf(self); // Do something with the 'context'.
        },
        deferEvaluation: true
    });
};

function ViewModel() {
    var self = this;
    self.rowArray = ko.observableArray([
        new RowModel('Zero', self),
        new RowModel('One', self),
        new RowModel('Two', self),
    ]);
};

这听起来有点麻烦,但似乎knockout基本上是在做同样的事情'under the hood'到compute $index:

Unlike the other binding context properties, $index is an observable and is updated whenever the index of the item changes