Foreach knockout with list of functions

I am having trouble binding foreach to a list of functions. I want the inner context to be the function itself, but instead the context is associated with the result of the function call. Here's a simple example to illustrate this: ( JSFiddle )

JS:

ko.applyBindings({
    list: [
        function() {
            return "hodor";
        }
    ]
});

      

HTML:

<!-- ko foreach: list -->
<span data-bind="text: typeof $data"></span>
<span data-bind="text: $data"></span>
<br />
<!-- /ko -->

      

Output: "string foo", but I would like it to be "function function () {return" foo ";}"

As a workaround, I can do it $parent.list[$index()]

, but this is really ugly and I would like to avoid this syntax if possible.

(For the sake of explanation in my real use these are not simple functions, but functions to which I have attached additional properties that I want to refer to, but I cannot refer to them because the knockout calls them)

EDIT:

There seems to be a KO version here. Until 3.0, this was not a problem, the context was always attached to a function not to a value. In version 3.0, using $rawData

, you get a function, not this value, but on 3.2, this is not what I am trying to use.

I updated the above fiddle to use 3.2 and here's a fiddle for every version including $rawData

(except 2.3 where $ rawData doesn't exist)

Knockout 2.3 Violin : $rawData

Not Required

Knockout 3.0 violin : $rawData

works

Knockout 3.2 Violin : $rawData

Doesn't Work.

Could this be a KO 3.2 bug?

+3


source to share


1 answer


No, that was a bug in KO 3.0.

In <2.3 this was a missing feature. Because without, $rawData

you could not work with arrays containing obsablez [ko.observable(1), ko.observable(2)]

.

It $rawData

was introduced in 3.0 , but it was a bug. This was fixed in 3.1 https://github.com/knockout/knockout/pull/1206 .

So this is the correct behavior presented by daedalus28 in the above linked issue:

$rawData

must be a return value if it is a function but not an observable. If it is an observable (or the result of a function is an observable) it should be unwrapped by $data

, not $rawData

- $rawData

should store the actual observable (the result of a function)

Your use case is currently not supported by KO.

So, you should use on, $parent.list[$index()]

or not directly put your functions into an array.

Wrap them up to the observable



 list: [
        ko.observable(function() {
            return "foo";   
        }),
        ko.observable(function() {
            return "bar";
        }),
        ko.observable(function() {
            return "hodor";
        })
    ]

      

Demo JSFiddle .

or put them on some mock objects:

list: [
    {bar: function() {
        return "foo";   
    }},
    {bar: function() {
        return "bar";
    }},
    {bar: function() {
        return "hodor";
    }}
]

      

And you write:

<span data-bind="text: bar"></span>

      

Demo JSFiddle .

+2


source







All Articles