JavaScript inside a component used inside Each breaks data binding

I found that whenever there is a JavaScript block inside the component UX, the data binding will break when it is used with Each. Sample scripts as follows.

SomeComponent.ux

<Panel ux:Class="SomeComponent">

    <JavaScript>
    ... blah blah blah ...
    </JavaScript>

    <Text Value="{name}" />
</Panel>

Main.ux

<App>

    <Panel>
        <Each Items="{some_observable}">
            <SomeComponent />
        </Each>
    </Panel>

</App>

I’m not sure how it’s breaking in your example, but I’m sure its supposed to since you for Every item in some_observabl you are re-executing the JS in the

Hi Vicker,

It is a little hard to make out what your problem is from your condensed snippet. Can you please provide a full test case?

When you have JavaScript inside an Each, the JS is evaluated for each item in the list, producing separate modules.

Thanks, Edwin and Anders.

Let me try to extract the snippets into a small project to illustrate.

In the mean time, let me further elaborate a bit. Let’s say the some_observable contains a list of 10 data objects. Without the JavaScript block in SomeComponent.ux, the data binding works correctly, displaying 10 items with the corresponding names.

However when there is a JavaScript block there, even the block itself contains nothing, it will break the data binding. i.e. it no longer shows any items as the Text is not able to bind name.

This is a small project to illustrate the problem.

MainView.ux

<App Theme="Basic">

    <JavaScript>
        var data = ["A", "B", "C", "D", "E"];

        module.exports = {
            data: data
        };
    </JavaScript>

    <StackPanel>
        <Each Items="{data}">
            <Component />
        </Each>
    </StackPanel>

</App>

Component.ux

<Panel ux:Class="Component">

    <JavaScript>
    </JavaScript>

    <Text FontSize="13" Value="{}" />

</Panel>

When the app launch, it failed to display the data using Text, unless the empty JavaScript block is removed.

Vicker, yes, this is a known limitation.

The empty binding {} in your case now refer to the empty module “exported” from the empty JavaScript block.

A work-around is:

<App Theme="Basic">

    <JavaScript>
        var data = [{label: "A"}, {label: "B"}, {label: "C"}];

        module.exports = {
            data: data
        };
    </JavaScript>

...

And in Component.ux:

<Panel ux:Class="Component">

    <JavaScript>
    </JavaScript>

    <Text FontSize="13" Value="{label}" />

</Panel>

Does this solve your problem? If it does, what we need here is some form of syntax to indicate you want to access the parent data context, for example:

<Text FontSize="13" Value="{^}" />

(Not implemented yet, just a suggestion).