如何获得observableArray的长度?

Kar*_*son 45 knockout.js

我正在尝试创建一系列合约订单项(CLIN),这些订单项将显示为div一般合约信息标题下的单个元素.

我能够使普通的observable工作,但似乎通过视图模型的构造函数传递数组不会创建clins可观察数组的任何部分.

我有一个jsFiddle来说明我的问题.对我来说奇怪的是,data-bind="text: clins.length()HTML span标签上甚至没有返回零,而是什么也没有呈现.

无论如何在jsFiddle中启用调试还是应该看到警告/错误?

ken*_*eiv 80

来自jsfiddle页面的错误会发送到您的浏览器.

至于你的错误,试试这个:

<span data-bind="text: clins().length">
Run Code Online (Sandbox Code Playgroud)

这将observableArray变成一个array并使用数组的length属性.

请参阅更新的jsfiddle.


Jer*_*oen 18

TL; DR /快速修复

执行observableArray函数以获取底层数组,然后获取其长度:

<!--                                                     ??                              -->
myObsArray's length is: <span data-bind="text: myObsArray().length"></span>
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

让我提供一个答案,除了@ kendaleiv的解决方案之外还提供一些细节,这也回答了我觉得很多人都有的高度相关的问题:

为什么myObsArray.length 总是返回0(零)?

这种情况的典型代表是:

ko.applyBindings({ myObsArray: ko.observableArray(["one", "two", "three"]) });
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
myObsArray.length = <span data-bind="text: myObsArray.length"></span>
Run Code Online (Sandbox Code Playgroud)

该片段显示"length = 0",而不是"length = 3".

这里需要注意的关键ko.observableArray是:函数... 返回一个函数.

这是正确的:如果将结果分配给变量或成员,例如myObsArray在示例中,该变量将是对函数的引用.所以如果你要求的话

myObsArray.length
Run Code Online (Sandbox Code Playgroud)

那么你实际上是要求Function.length属性:参数,参数函数需要的数量.对于从此返回的函数ko.observableArray将为0(零).

我们如何解决这个问题?

其他答案中给出的修正很好,让我在这里重申这个答案的例子.要获得"正在观察的数组"的长度,您需要调用所述函数来获取数组,然后获取其长度:

ko.applyBindings({ myObsArray: ko.observableArray(["one", "two", "three"]) });
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
myObsArray.length = <span data-bind="text: myObsArray().length"></span>
Run Code Online (Sandbox Code Playgroud)


最后,作为脚注,OP的代码相当于:

myObsArray.length()
Run Code Online (Sandbox Code Playgroud)

这将找到前面提到的Function.length属性并尝试将其作为一个函数执行(它不是),并且不会返回0而是崩溃.注意不要length作为函数调用,而是可观察的.始终length作为成员变量调用.

会/可以/可以改变吗?

很早就KO的开发人员考虑过这个问题; 早在Github发行第4期.这个问题解释了我上面试图涵盖的内容,并且还表明最终没有太多可以做的改变它.


Dav*_*ret 5

对于想要获得没有_destroyed项的observableArray长度的任何人,您可以使用此函数:

ko.observableArray.fn.totalVisible = function() {
    var items = this(), count = 0;

    if (items == null || typeof items.length === "undefined") {
        return 0;
    }

    for (var i = 0, l = items.length; i < l; i++) {
        if (items[i]._destroy !== true) {
            count++;
        }
    }

    return count;
};
Run Code Online (Sandbox Code Playgroud)

然后使用它:

myObservableArray.totalVisible();
Run Code Online (Sandbox Code Playgroud)