如何在foreach中的Knockout组件中访问数组成员?

时间:2015-10-30 17:18:28

标签: javascript knockout.js

我无法使Knockout组件正常工作 - 在使用foreach访问$index期间,我似乎无法将其正确绑定到ViewModel上的数组成员。< / p>

this Fiddle中你会看到我的意思。

有两种小视图模型:

function OtherThingViewModel(thingString){
   this.thingString = ko.observable(thingString);
}

function ThingViewModel(thingNumber, thing){
    this.thingNumber = ko.observable(thingNumber);
}

在主viewModel:

中创建实例
function ViewModel(){
    var self = this;

    this.things = [ 
        new ThingViewModel(1),
        new ThingViewModel(2),
        new ThingViewModel(3)
    ];

    this.otherThings = [ 
        new OtherThingViewModel("a Thing"),
        new OtherThingViewModel("another Thing"),
        new OtherThingViewModel("some Thing")
    ];

    this.specialThing = ko.unwrap(this.things)[0];
    this.specialOtherThing = ko.unwrap(this.otherThings)[0];
};

然后我有一个组件:

ko.components.register('combinedthing-component', {
    template:
    '<div>'
    + ' <h3 data-bind="text: \'Thing \' + thing.thingNumber()"></h3>'
    + ' <p>'
    + '     <label>thingNumber: <input data-bind="value: thing.thingNumber" /></label>'
    + '     <span data-bind="text: thing.thingNumber" />'
    + ' </p>'
    + ' <p>'
    + '     <label>thingString: <input data-bind="value: otherThing.thingString" /></label>'
    + '     <span data-bind="text: otherThing.thingString" />'
    + ' </p>'
    + ' <p data-bind="text: JSON.stringify(ko.unwrap(otherThing))"></p>'
    + '</div>'
});

用于显示两个视图模型的数据。

在HTML中我可以成功使用该组件并使用foreach我可以组合这两个对象:

<h1>1 component</h1>
<combinedthing-component params="thing: specialThing, otherThing: specialOtherThing"></combinedthing-component>

<h1>Foreach</h1>
<!-- ko foreach: things -->
    <div>
        <h3 data-bind="text: 'Thing ' + thingNumber()"></h3>
        <p>
            <label>thingNumber <Input data-bind="value: thingNumber" /></label>
            <span data-bind="text: thingNumber" />
        </p>
        <p>
            <label>thingString: <input data-bind="value: $root.otherThings[$index()].thingString" /></label>
            <span data-bind="text: $root.otherThings[$index()].thingString" />
        </p>
    </div>
<!-- /ko -->

但是如果我尝试将两个循环的thingsforeach结合起来,然后使用$ index访问otherThings数组并将它们绑定到组件:

<h1>Many Components</h1>
<!-- ko foreach: things -->
    <combinedthing-component params="thing: $data, otherThing: $root.otherThings[$index()]"></combinedthing-component>
<!-- /ko -->

然后,当我在otherThing中获得一个对象时(由ko.toJSON绑定证明),其属性不会绑定到inputspan

是什么给出了?

1 个答案:

答案 0 :(得分:1)

问题是由于在使用&#34; web组件&#34;时将params传递到组件中的方式。句法。通过params=""传递的对象将转换为依赖的observable(计算)。在幕后,$root.otherThings[$index()]基本上成为这个实现function () { return $root.otherThings[$index()]; }的计算可观察对象。

最简单的方法是在引用ko.utils.unwrapObservable时获得所需内容otherThing。这样可以确保您始终使用实际的otherThing代替包含它的可观察对象。

<label>thingString: <input data-bind="value: ko.utils.unwrapObservable(otherThing).thingString" /></label>
<span data-bind="text: ko.utils.unwrapObservable(otherThing).thingString" />

执行此展开的理想位置是组件注册的视图模型部分。

JSFiddle