Loop Display
Repeater
Applicable Scenarios
For scenarios using the Loop Display component, you can loop through an array to display its contents on the page, such as iterating through a news list.
Note: You need to upgrade to the latest component library to use this component.
Basic Capabilities Description
1. Loop through an array and display it
Drag a Loop Display component, which comes with a text by default. You can see the text is displayed in a loop 3 times.
In the example, the text component displays the loop index number and the `name` field because the text concatenates an expression bound to `index`. and the `name` field.
2. Obtaining the loop index
Within the Loop Display component, the current loop index can be obtained, as shown:

Application Example
Create a new variable of type array. A record of array type is created, and the data is displayed.
First, create a new variable list, as shown in the figure below:


Then bind the variable list to the [Data] property of the Loop Display component.

Drag a text component into the loop, open the expression editor, select the age field in the loop object to display the age information from the variable. Similarly, other data can also be obtained.

Extended Scenarios Description
Multi-level Nesting of Loop Components Simulating Shopping Cart Product Selection
- Create array variable [goods]:

[
{
key: '0',
name: name: 'Product 1',
checked: true,
children: [
{
key: '01',
name: name: 'Apple',
checked: true,
iconType: 'td:check-rectangle-filled'
},
{
key: '02',
name: name: 'Orange',
checked: true,
iconType: 'td:check-rectangle-filled'
},
{
key: '03',
name: name: 'Banana',
checked: true,
iconType: 'td:check-rectangle-filled'
}
],
iconType: 'td:check-rectangle-filled'
},
{
key: '1',
name: name: 'Product 2',
checked: false,
children: [
{
key: '011',
name: name: 'Apple 1',
checked: false,
iconType: 'td:rectangle'
},
{
key: '022',
name: name: 'Orange 2',
checked: false,
iconType: 'td:rectangle'
},
{
key: '033',
name: name: 'Banana 3',
checked: false,
iconType: 'td:rectangle'
}
],
iconType: 'td:rectangle'
}
];
- Create boolean type variable [goodsStatus]:
- Used to store the global checked status

- Create update data method [updateTree]:

export default function ({ data }) {
const { targetNode, checked } = data.target;
const _treeData = $w.page.dataset.state.goods;
let treeData = JSON.parse(JSON.stringify(_treeData));
treeData = uptateItem({ treeData, targetNode, checked });
return updateParent(treeData);
}
const uptateItem = ({ treeData, targetNode, checked }) => {
const queue = [];
const index = treeData.findIndex((_) => _.key === targetNode.key);
if (index > -1) {
let menu = treeData[index];
treeData.splice(index, 1, {
...menu,
checked,
iconType: checked ? 'td:check-rectangle-filled' : 'td:rectangle',
children: $w.page.handler.updateChildren({
data: { target: { children: menu?.children, checked } }
})
});
return treeData;
}
treeData.forEach((_) => queue.push(_));
while (queue.length) {
const node = queue.shift();
if (!node) return treeData;
if (node.children?.length) {
const index = node.children.findIndex((_) => _.key === targetNode.key);
const menu = node.children[index];
if (index > -1) {
node.children.splice(index, 1, {
...menu,
checked,
iconType: checked ? 'td:check-rectangle-filled' : 'td:rectangle',
children: $w.page.handler.updateChildren({
data: { target: { children: menu?.children, checked } }
})
});
return treeData;
}
node.children.forEach((_) => queue.push(_));
}
}
return treeData;
};
const updateParent = (treeData) => {
return treeData.map((i) => {
if (i.children) {
const item = { ...i };
const checkedList = i.children.filter((j) => j.checked);
item.iconType =
i.children.length === checkedList.length
? 'td:check-rectangle-filled'
: checkedList.length === 0
? 'td:rectangle'
: 'td:minus-rectangle';
item.checked = i.children.length === checkedList.length;
const children = updateParent(item.children);
return { ...item, children };
} else {
return i;
}
});
};
- Create update children method [updateChildren]:
export default function ({ event, data }) {
const { children, checked } = data.target;
return updateChildren(children, checked);
}
const updateChildren = (children, checked) => {
return children?.map((i) => {
const item = { ...i };
item.iconType = checked ? 'td:check-rectangle-filled' : 'td:rectangle';
item.checked = checked;
if (i.children) {
const _children = updateChildren(i.children, checked);
return { ...item, children: _children };
}
return item;
});
};
- Create update global product selection status method [updateGoods]:
export default function ({ event, data }) {
const checked = !$w.page.dataset.state.goodsStatus;
const goods = updateGoods(checked);
$page.setState({ goods, goodsStatus: checked });
}
const updateGoods = (checked) => {
return $w.page.dataset.state.goods.map((i) => {
return {
...i,
checked,
iconType: checked ? 'td:check-rectangle-filled' : 'td:rectangle',
children: $w.page.handler.updateChildren({
data: { target: { children: i.children, checked } }
})
};
});
};
- Drag in a loop component and assemble it according to the expected effect:
- Bind the variable [goods] to the first layer loop

- Bind the second layer loop to $w.item_repeater1.children, and if there is a third layer, use $w.item_repeater2.children and so on

- The selection status is displayed using icons and managed through the variable [goods]
- Bind the selection click event:

- Input parameters:
({ targetNode: $w.item_repeater1, checked: !$w.item_repeater1.checked });
Output parameters: Performing variable assignment
After successfully assigning [goods], update [goodsStatus]

$w.page.dataset.state.goods.length ===
$w.page.dataset.state.goods.filter((i) => i.checked).length;
- Add components; manage global state
- Add text to display the select-all status

$w.page.dataset.state.goodsStatus ? 'Select All' : 'Not all selected';
- Add an icon to display the binding status
$w.page.dataset.state.goodsStatus
? 'td:check-rectangle-filled'
: 'td:rectangle';
- Bind the event

The following video demonstrates how to implement multi-level loop nesting and checkbox state management:
Properties
External properties received by the component
Property Name | Property Identifier | Type | Description |
|---|
| Data. | data | array | Array data used to generate loops |
| Data primary key | key | string | Save loop member status with loop object attribute named as flag |
Properties API
Through the Property API, you can access the internal state and property values of components. You can access internal values using$w.componentId.propertyName, such as $w.input1.value. For details, please refer to Property API
Read-only Property Name | Property Identifier | Type | Description |
|---|
| Loop data | data | array | Retrieve loop data |
Inventory Compatibility Notice
Since January 2023, to use this component, you need to first upgrade to the latest component library. The loop display property of older versions will no longer be supported. Already configured applications will not be affected during runtime.
