Loop Display
Repeater
Applicable Scenarios
Loop display components can be used to display an array
in a loop on the page, such as for a news list.
Note: You must upgrade to the latest component library to use this component.
Basic Capabilities Description
1. Loop through an array and display
Drag and drop a loop display component, which includes a text component by default. You can see that the text has been displayed in a loop 3 times.
In the example, the text component displays the loop index number and the
name
field by concatenating expressions bound to the index
and name
fields.
2. Get the loop index
Within the Loop Display Component, you can obtain the current loop index, as shown in the figure below:
Application Example
Create a new array variable and display the data.
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 'Age' in the Loop Object
to display the age information from the variable. Other data can be obtained in the same way.
Extended Scenarios Description
Multi-layer Nesting of Loop Components to Simulate Shopping Cart Item Selection
- Create an array variable [goods]:
[
{
key: '0',
name: 'Product 1',
checked: true,
children: [
{
key: '01',
name: 'Apple',
checked: true,
iconType: 'td:check-rectangle-filled',
},
{
key: '02',
name: 'Orange',
checked: true,
iconType: 'td:check-rectangle-filled',
},
{
key: '03',
name: 'Banana',
checked: true,
iconType: 'td:check-rectangle-filled',
},
],
iconType: 'td:check-rectangle-filled',
},
{
key: '1',
name: 'Product 2',
checked: false,
children: [
{
key: '011',
name: 'Apple1',
checked: false,
iconType: 'td:rectangle',
},
{
key: '022',
name: 'Orange2',
checked: false,
iconType: 'td:rectangle',
},
{
key: '033',
name: 'Banana3',
checked: false,
iconType: 'td:rectangle',
},
],
iconType: 'td:rectangle',
},
];
- Create a Boolean variable [goodsStatus]:
- For storing the global checked status
- Create a method for updating data [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 a method for updating child nodes [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 a method to update the global product selection status [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 a loop component and assemble according to the expected effect:
- Bind the variable [goods] in the first-level loop
- Bind [$w.item_repeater1.children] in the second-level loop. If there is a third level, use [$w.item_repeater2.children] and so on
- The checked status is displayed using icons and managed in the variable [goods]
- Bind the check click event:
- Input Parameters:
({ targetNode: $w.item_repeater1, checked: !$w.item_repeater1.checked });
Output: Execute variable assignment
After successfully assigning a value to [goods], update [goodsStatus]
$w.page.dataset.state.goods.length ===
$w.page.dataset.state.goods.filter((i) => i.checked).length;
- Add components to manage the global state
- Add text to display the select-all status
$w.page.dataset.state.goodsStatus ? 'Select All' : 'Not All Selected';
- Add an icon to bind and display the 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 check status management:
Properties
组件接收的外部传入的属性
属性名 | 属性标识 | 类型 | 说明 |
---|
数据 | data | array | 用于产生循环的数组数据 |
数据主键 | key | string | 以循环对象属性名为标识保存循环成员状态 |
Property API
通过属性 API,可以获取组件内部的状态和属性值,可以通过$w.componentId.propertyName
来访问组件内部的值,如 $w.input1.value
,详请请参考 属性 API
只读属性名 | 属性标识 | 类型 | 说明 |
---|
循环数据 | data | array | 获取循环的数据 |
Legacy Compatibility Notice
Since January 2023, using this component requires upgrading to the latest component library first. The loop display properties of older versions will no longer be supported, though configured applications remain unaffected at runtime.