如何在foreach的Knockout组件中访问数组成员? [英] How do I access array members in a Knockout component in a foreach?

查看:150
本文介绍了如何在foreach的Knockout组件中访问数组成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am having trouble getting a Knockout component to work - i can't seem to get it to bind properly to the members of an array on my ViewModel during a foreach accessed using $index.

这个小提琴中,您会明白我的意思.

In this Fiddle you will see what I mean.

有两个小视图模型:

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

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

在主viewModel中创建实例:

Instances are created in the main 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>'
});

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

for displaying data from the two view models.

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

In the HTML I can successfully use the the component and using a foreach I can combine the two objects:

<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数组并将其绑定到组件:

but if I try and combine the two - looping thorugh things with the foreach and then accessing the otherThings Array using $index and binding these to the component:

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

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

Then while I get an object in otherThing (as proved by the ko.toJSON binding) its properties are not binding to the input and span.

有什么作用?

推荐答案

问题是由于使用"Web组件"语法时如何将参数传递到组件中而引起的.通过params=""传递的对象将转换为相关的可观察对象(计算的).在后台,$root.otherThings[$index()]本质上成为此实现function () { return $root.otherThings[$index()]; }的计算可观察到的结果.

The problem is due to how params are passed into a component when using the "web component" syntax. The objects passed through params="" get transformed into dependent observables (computeds). Behind the scenes, $root.otherThings[$index()] essentially becomes a computed observable with this implementation function () { return $root.otherThings[$index()]; }.

最简单的方法是在引用otherThing时添加所需的内容.这将确保您始终使用实际的otherThing而不是可观察的包装.

The simplest way is to get what you want is to add a ko.utils.unwrapObservable when referencing otherThing. This will ensure that you're always working with the actual otherThing instead of an observable wrapping it.

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

执行此解包的理想位置是组件注册的视图模型部分.

The ideal place to do this unwrapping would be in view model part of the component registration.

JSFiddle

这篇关于如何在foreach的Knockout组件中访问数组成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆