Dynamic repeaters are repeaters that are intended to get their content dynamically. This means that their content can only come through a connection to a CMS collection, or through code. You cannot edit the content of each individual item directly on the canvas.
There are several ways to nest a dynamic repeater in another dynamic repeater. We recommend using nested widgets and drilling their properties.
This article uses a menu app as an example. Here is the app structure:
There are two collections in the app:
MenuSections
: The outer collection, which stores sections.RestaurantDishes
: The inner one, which stores dishes.Here's what the general structure of the app looks like:
In this option uses nested widgets. The app has three widgets:
menuWidget
: The top level widget, representing the entire menu.sectionWidget
: Represents each section and is nested in menuWidget
.dishWidget
: Represents each individual dish and is nested in sectionWidget
The top level widget, menuWidget
holds a repeater with the menu sections. It connects this repeater to the MenuSections
collection using no code.
Since sectionWidget
(the second level widget), has a repeater that connects to the RestaurantDishes
collection, the top level widget can query both collections at once, using the include()
method. All the information is then passed to the nested widgets through prop drilling.
Here is the code for menuWidget
:
The sectionWidget
has two widget properties:
dishes [Dish]
: A list of a properties of a custom type representing a dish.sectionTitle
: A text property for the section's title.Here is the code for sectionWidget
:
The dishWidget
has three simple properties:
title
: Text property for the dish name.description
: Text property for the dish description.image
: Image property for the dish.This is the code for dishWidget
:
For this option, the app structure is simplified:
menuWidget
: The top-level widget with a repeater connected to the main MenuSections
collection.sectionWidget
: A nested widget with a repeater connected to the RestaurantDishes
collection.sectionId
and sectionTitle
.Both repeaters connect their elements (texts and images) to their respective collections with no code.
The menuWidget
uses code to pass the sectionId
and sectionTitle
to the nested widget, as widget properties cannot be connected to data with no code.
Notice that since the repeater is connected to a collection with no code, you can call onItemReady()
without setting the repeater data explicitely.
Here is the code for menuWidget
:
The sectionWidget
filters the repeater with the the sectionId
and displays only the relevant dishes.
Here is the code for sectionWidget
:
Notice that because the repeaters are nested, each of the collections receives a field that references to the dataset of the other collection.
This option uses a single widget with nested repeaters.
This is the widget structure:
sections
. It connects to the MenuSections
collection.dishes
. It connects to the RestaurantDishes
collection.The following query fetches the data from both collections, using the include()
method.
Here is the widget code:
In this option, the outer repeater is connected to the MenuSections
collection using no-code data binding. However, since only the top-level repeater can use data binding when nesting repeaters, the inner repeater must be connected programmatically.
To populate the inner repeater, we query its items using queryReferenced()
. While this approach works, it is more performance-costly than the previous options because it requires an additional query for each nested item.