My application contains multiple LayoutInfoBox controls, each with several child components.
How can I count how many child components inside a specific LayoutInfoBox are of the Button type and how many are of the Text type?
Additionally, how do I determine whether a child component’s parent container is LayoutInfoBox_1 or LayoutInfoBox_2?
of course,use Instance.Button_1.parent , how I get the name ‘LayoutInfoBox_1’ ?
How to determine whether a component’s parent is layoutInfoBox_1?
In the code definition, Instance.XXX.parent is an HTML Element. Class: Component_A
So the object you get by calling the Instance.XX.parent interface is definitely not an Instance.
To answer your question about obtaining the parent-child component relationship:
- If you are deploying in a non-responsive mode, unfortunately, rendering happens all at once. It’s impossible to obtain parent-child relationships via DOM structure. Similarly, even if you manage to gather some information through DOM bubbling, it only pertains to the current visible interface, which has limitations.
- If it is deployed in Lifecycle mode, you can traverse the objects under Instance to find their relationships. Here is a sample code, though it is just for demonstration purposes
/**
* Direct Children Search: Finds only the first-level component instances.
* It penetrates technical wrappers (like child, content) but stops searching
* deeper once a real component node (with compId) is found.
* * @param {Object|Array} obj - The current starting node (e.g., a Page or Tab instance).
* @param {Array} results - Internal accumulator for the direct children.
* @param {Boolean} isRoot - Internal flag to distinguish the root node from its sub-branches.
* @returns {Array} An array of direct first-level component instances.
*/
function findTDirectChildren(obj, results = [], isRoot = true) {
if (typeof obj !== 'object' || obj === null) return results;
// If the current object is an array, iterate through its items
if (Array.isArray(obj)) {
for (const item of obj) {
findTDirectChildren(item, results, false);
}
return results;
}
// If this is NOT the root node, and we encounter a real component (has compId)
if (!isRoot && obj.compId && typeof obj.compId === 'string') {
if (!results.includes(obj)) {
results.push(obj); // Collect it as a direct child
}
return results; // CRITICAL: Stop diving deeper into this component's subtree!
}
// Dynamic Scan: Penetrate layout or abstract wrappers (child, content, etc.)
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
const value = obj[key];
if (typeof value === 'object' && value !== null) {
findTDirectChildren(value, results, false);
}
}
}
return results;
}
/**
* Smart Parent Finder: Traverses the tree and leverages `findTDirectChildren`
* to check if the target object exists in any node's immediate child list.
* * @param {Object} currentObj - The root Instance or current node being scanned.
* @param {Object} targetObj - The exact child object/instance you want to find the parent for.
* @param {Set} visited - Guard against infinite loops from circular references.
* @returns {Object|null} The exact direct parent component instance, or null.
*/
function findTDirectParent(currentObj, targetObj, visited = new Set()) {
if (typeof currentObj !== 'object' || currentObj === null) return null;
if (visited.has(currentObj)) return null;
visited.add(currentObj);
// 1. Check if the current node is a real component
const isRealComponent = currentObj.compId && typeof currentObj.compId === 'string';
if (isRealComponent) {
// 2. Use your smart function to get ONLY the first-level direct children of this component
const directChildren = findTDirectChildren(currentObj);
// 3. If the target is found inside its direct children, this node IS the parent!
if (directChildren.includes(targetObj)) {
return currentObj;
}
}
// 4. Otherwise, continue searching down the tree to check other components
for (const key in currentObj) {
if (currentObj.hasOwnProperty(key)) {
const value = currentObj[key];
if (typeof value === 'object' && value !== null) {
if (Array.isArray(value)) {
for (const item of value) {
const foundParent = findTDirectParent(item, targetObj, visited);
if (foundParent) return foundParent;
}
} else {
const foundParent = findTDirectParent(value, targetObj, visited);
if (foundParent) return foundParent;
}
}
}
}
return null;
}
findTDirectParent(Instance, Instance.Button_5)
// Page {events: {…}, initialized: true, noCheck: Array(0), _initPropsDependencies: Array(0), _props: {…}, …}
findTDirectChildren(Instance.LayoutInfobox_1)
// (3) [Input, Image, Container_A]
thank you replay. I have simple question,why the component not a ‘name’ property? why can’t use a NAME access a component?
Good point! We can’t do this right now due to some legacy issues, but we’ll definitely discuss it for future updates