Hi Wodger,
let’s answer those three questions separately.
Is there a way to pass the entire object as a ux:Property?
The answer is yes, but not in the context you are asking. So: no. Instead, the entire object [of iterated item] is implicitly available to the ux:Class. Consider the following code:
<App>
<JavaScript>
var Observable = require("FuseJS/Observable");
var list = Observable(
new Item("item one"),
new Item("item two"),
new Item("item three")
);
function Item(label) {
this.label = label;
}
module.exports = {
items: list
};
</JavaScript>
<Panel ux:Class="ListItem" Height="56">
<Text Value="{label}" Alignment="Center" Color="#000a" />
<Rectangle Color="#0003" CornerRadius="2" />
</Panel>
<ClientPanel Color="#f003">
<ScrollView>
<StackPanel ItemSpacing="2" Margin="2">
<Each Items="{items}">
<ListItem />
</Each>
</StackPanel>
</ScrollView>
</ClientPanel>
</App>
What if I need to do something to a ux:Property
before it’s displayed?
One way would be to do that in the original data source, in the object itself - so that you don’t have to do anything after. The other way involves defining separate ux:Property
for each item property you need and manipulating them in component-local scope. Consider the following code:
<App>
<JavaScript>
var Observable = require("FuseJS/Observable");
var list = Observable(
new Item("item one"),
new Item("item two"),
new Item("item three")
);
function Item(label) {
this.label = label;
}
module.exports = {
items: list
};
</JavaScript>
<Panel ux:Class="ListItem" Height="56">
<JavaScript>
var localLabel = this.Label.map(function(x) {
return "this is " + x;
});
module.exports = {
localLabel: localLabel
};
</JavaScript>
<string ux:Property="Label" />
<Text Value="{localLabel}" Alignment="Center" Color="#000a" />
<Rectangle Color="#0003" CornerRadius="2" />
</Panel>
<ClientPanel Color="#f003">
<ScrollView>
<StackPanel ItemSpacing="2" Margin="2">
<Each Items="{items}">
<ListItem Label="{label}" />
</Each>
</StackPanel>
</ScrollView>
</ClientPanel>
</App>
And finally,
Is there a way to get the index each item produced by Each?
Not directly, no. There are no implicit magic indexes. However, you can easily add some yourself! Consider the following code:
<App>
<JavaScript>
var Observable = require("FuseJS/Observable");
var list = Observable(
new Item("item one"),
new Item("item two"),
new Item("item three")
);
var indexedList = list.map(function(itm, idx) {
return {index: idx, item: itm};
});
function Item(label) {
this.label = label;
}
module.exports = {
items: indexedList
};
</JavaScript>
<Panel ux:Class="ListItem" Height="56">
<JavaScript>
var localLabel = this.Label.map(function(x) {
return "this is " + x;
});
module.exports = {
localLabel: localLabel
};
</JavaScript>
<string ux:Property="Label" />
<Text Value="{index}: {localLabel}" Alignment="Center" Color="#000a" />
<Rectangle Color="#0003" CornerRadius="2" />
</Panel>
<ClientPanel Color="#f003">
<ScrollView>
<StackPanel ItemSpacing="2" Margin="2">
<Each Items="{items}">
<ListItem Label="{item.label}" />
</Each>
</StackPanel>
</ScrollView>
</ClientPanel>
</App>
Note how inside of the ux:Class
we can use both {index}
from the iterated object directly, and {localLabel}
from component-local scope.