Recursive lightning component - how to know when it's fully rendered?
I’ve got a lightning component that creates itself recursively and asynchronously in order to fully render a tree-structure data. Here’s a sample code that simplifies the problem.
TestApp.app
<aura:application>
<ul>
<c:node level="3"/>
</ul>
</aura:application>
Node.cmp
<aura:component>
<aura:attribute name="level" type="Integer" />
<aura:attribute name="children" type="List" access="private" />
<aura:handler name="init" value="{!this}" action="{!c.createChildren}"/>
<li>
Level {!v.level}
<ul>
<aura:iteration items="{!v.children}" var="child">
<c:node level="{!v.level - 1}" />
</aura:iteration>
</ul>
</li>
</aura:component>
NodeController.js
({
createChildren : function(component, event, helper) {
var level = component.get('v.level'),
children = ;
for (var i = 0; i < level; i++) {
children.push({});
}
component.set("v.children", children);
}
})
DEMO
QUESTION
How can the app know when the the full tree has been rendered?
In my use case, the controller.js is a server call so it's possible some nodes could finish sooner having no children, while some can continue expanding.
lightning-aura-components
add a comment |
I’ve got a lightning component that creates itself recursively and asynchronously in order to fully render a tree-structure data. Here’s a sample code that simplifies the problem.
TestApp.app
<aura:application>
<ul>
<c:node level="3"/>
</ul>
</aura:application>
Node.cmp
<aura:component>
<aura:attribute name="level" type="Integer" />
<aura:attribute name="children" type="List" access="private" />
<aura:handler name="init" value="{!this}" action="{!c.createChildren}"/>
<li>
Level {!v.level}
<ul>
<aura:iteration items="{!v.children}" var="child">
<c:node level="{!v.level - 1}" />
</aura:iteration>
</ul>
</li>
</aura:component>
NodeController.js
({
createChildren : function(component, event, helper) {
var level = component.get('v.level'),
children = ;
for (var i = 0; i < level; i++) {
children.push({});
}
component.set("v.children", children);
}
})
DEMO
QUESTION
How can the app know when the the full tree has been rendered?
In my use case, the controller.js is a server call so it's possible some nodes could finish sooner having no children, while some can continue expanding.
lightning-aura-components
add a comment |
I’ve got a lightning component that creates itself recursively and asynchronously in order to fully render a tree-structure data. Here’s a sample code that simplifies the problem.
TestApp.app
<aura:application>
<ul>
<c:node level="3"/>
</ul>
</aura:application>
Node.cmp
<aura:component>
<aura:attribute name="level" type="Integer" />
<aura:attribute name="children" type="List" access="private" />
<aura:handler name="init" value="{!this}" action="{!c.createChildren}"/>
<li>
Level {!v.level}
<ul>
<aura:iteration items="{!v.children}" var="child">
<c:node level="{!v.level - 1}" />
</aura:iteration>
</ul>
</li>
</aura:component>
NodeController.js
({
createChildren : function(component, event, helper) {
var level = component.get('v.level'),
children = ;
for (var i = 0; i < level; i++) {
children.push({});
}
component.set("v.children", children);
}
})
DEMO
QUESTION
How can the app know when the the full tree has been rendered?
In my use case, the controller.js is a server call so it's possible some nodes could finish sooner having no children, while some can continue expanding.
lightning-aura-components
I’ve got a lightning component that creates itself recursively and asynchronously in order to fully render a tree-structure data. Here’s a sample code that simplifies the problem.
TestApp.app
<aura:application>
<ul>
<c:node level="3"/>
</ul>
</aura:application>
Node.cmp
<aura:component>
<aura:attribute name="level" type="Integer" />
<aura:attribute name="children" type="List" access="private" />
<aura:handler name="init" value="{!this}" action="{!c.createChildren}"/>
<li>
Level {!v.level}
<ul>
<aura:iteration items="{!v.children}" var="child">
<c:node level="{!v.level - 1}" />
</aura:iteration>
</ul>
</li>
</aura:component>
NodeController.js
({
createChildren : function(component, event, helper) {
var level = component.get('v.level'),
children = ;
for (var i = 0; i < level; i++) {
children.push({});
}
component.set("v.children", children);
}
})
DEMO
QUESTION
How can the app know when the the full tree has been rendered?
In my use case, the controller.js is a server call so it's possible some nodes could finish sooner having no children, while some can continue expanding.
lightning-aura-components
lightning-aura-components
asked 2 hours ago
jmrjulianjmrjulian
1,3861322
1,3861322
add a comment |
add a comment |
2 Answers
2
active
oldest
votes
Have node include an event that says when it is done. It is considered done when all of its children are considered done. If it has nothing to expand, it is done at the end of the server call. Otherwise, each time a child says it's done, check to see if there are any pending. Something like this:
<aura:component>
<aura:attribute name="level" type="Integer" />
<aura:attribute name="children" type="List" access="private" />
<aura:attribute name="counter" type="Integer" default="0" />
<aura:handler name="init" value="{!this}" action="{!c.createChildren}"/>
<aura:registerEvent name="done" type="c:genericEvent" />
<li>
Level {!v.level}
<ul>
<aura:iteration items="{!v.children}" var="child">
<c:node level="{!v.level - 1}" done="{!c.check}" />
</aura:iteration>
</ul>
</li>
</aura:component>
({
createChildren : function(component, event, helper) {
var level = component.get('v.level'),
children = ;
for (var i = 0; i < level; i++) {
children.push({});
}
component.set("v.children", children);
if(!children.length) {
component.getEvent("done").fire();
}
},
check: function(component, event, helper) {
component.set("v.counter", 1 + component.get("v.counter"));
if(component.get("v.counter") === component.get("v.children").length) {
component.getEvent("done").fire();
}
}
})
The application just listens for that event, too:
<aura:application>
<ul>
<c:node level="3" done="{!c.nodesLoaded}" />
</ul>
</aura:application>
N.B. I didn't actually test this, but it should be simple enough to spot any obvious mistakes, I think.
Wow. I've been on this all day!
– jmrjulian
31 mins ago
add a comment |
Your situation is tricky but if you know how many component will be created then you can tell the tree is fully loaded. You need to have a variable at root level which will tell you the total component count.
Each child component should speak with their parent after it is loaded, assuming parent node is loading and then child node is loading. Use below out of the box event along with custom event to communicate with parent.
<aura:handler name="render" value="{!this}" action="{!c.onRender}"/>
Any reason lightning tree cannot be used. If the JSON is not that big you can keep appending it.
add a comment |
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "459"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f247064%2frecursive-lightning-component-how-to-know-when-its-fully-rendered%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Have node include an event that says when it is done. It is considered done when all of its children are considered done. If it has nothing to expand, it is done at the end of the server call. Otherwise, each time a child says it's done, check to see if there are any pending. Something like this:
<aura:component>
<aura:attribute name="level" type="Integer" />
<aura:attribute name="children" type="List" access="private" />
<aura:attribute name="counter" type="Integer" default="0" />
<aura:handler name="init" value="{!this}" action="{!c.createChildren}"/>
<aura:registerEvent name="done" type="c:genericEvent" />
<li>
Level {!v.level}
<ul>
<aura:iteration items="{!v.children}" var="child">
<c:node level="{!v.level - 1}" done="{!c.check}" />
</aura:iteration>
</ul>
</li>
</aura:component>
({
createChildren : function(component, event, helper) {
var level = component.get('v.level'),
children = ;
for (var i = 0; i < level; i++) {
children.push({});
}
component.set("v.children", children);
if(!children.length) {
component.getEvent("done").fire();
}
},
check: function(component, event, helper) {
component.set("v.counter", 1 + component.get("v.counter"));
if(component.get("v.counter") === component.get("v.children").length) {
component.getEvent("done").fire();
}
}
})
The application just listens for that event, too:
<aura:application>
<ul>
<c:node level="3" done="{!c.nodesLoaded}" />
</ul>
</aura:application>
N.B. I didn't actually test this, but it should be simple enough to spot any obvious mistakes, I think.
Wow. I've been on this all day!
– jmrjulian
31 mins ago
add a comment |
Have node include an event that says when it is done. It is considered done when all of its children are considered done. If it has nothing to expand, it is done at the end of the server call. Otherwise, each time a child says it's done, check to see if there are any pending. Something like this:
<aura:component>
<aura:attribute name="level" type="Integer" />
<aura:attribute name="children" type="List" access="private" />
<aura:attribute name="counter" type="Integer" default="0" />
<aura:handler name="init" value="{!this}" action="{!c.createChildren}"/>
<aura:registerEvent name="done" type="c:genericEvent" />
<li>
Level {!v.level}
<ul>
<aura:iteration items="{!v.children}" var="child">
<c:node level="{!v.level - 1}" done="{!c.check}" />
</aura:iteration>
</ul>
</li>
</aura:component>
({
createChildren : function(component, event, helper) {
var level = component.get('v.level'),
children = ;
for (var i = 0; i < level; i++) {
children.push({});
}
component.set("v.children", children);
if(!children.length) {
component.getEvent("done").fire();
}
},
check: function(component, event, helper) {
component.set("v.counter", 1 + component.get("v.counter"));
if(component.get("v.counter") === component.get("v.children").length) {
component.getEvent("done").fire();
}
}
})
The application just listens for that event, too:
<aura:application>
<ul>
<c:node level="3" done="{!c.nodesLoaded}" />
</ul>
</aura:application>
N.B. I didn't actually test this, but it should be simple enough to spot any obvious mistakes, I think.
Wow. I've been on this all day!
– jmrjulian
31 mins ago
add a comment |
Have node include an event that says when it is done. It is considered done when all of its children are considered done. If it has nothing to expand, it is done at the end of the server call. Otherwise, each time a child says it's done, check to see if there are any pending. Something like this:
<aura:component>
<aura:attribute name="level" type="Integer" />
<aura:attribute name="children" type="List" access="private" />
<aura:attribute name="counter" type="Integer" default="0" />
<aura:handler name="init" value="{!this}" action="{!c.createChildren}"/>
<aura:registerEvent name="done" type="c:genericEvent" />
<li>
Level {!v.level}
<ul>
<aura:iteration items="{!v.children}" var="child">
<c:node level="{!v.level - 1}" done="{!c.check}" />
</aura:iteration>
</ul>
</li>
</aura:component>
({
createChildren : function(component, event, helper) {
var level = component.get('v.level'),
children = ;
for (var i = 0; i < level; i++) {
children.push({});
}
component.set("v.children", children);
if(!children.length) {
component.getEvent("done").fire();
}
},
check: function(component, event, helper) {
component.set("v.counter", 1 + component.get("v.counter"));
if(component.get("v.counter") === component.get("v.children").length) {
component.getEvent("done").fire();
}
}
})
The application just listens for that event, too:
<aura:application>
<ul>
<c:node level="3" done="{!c.nodesLoaded}" />
</ul>
</aura:application>
N.B. I didn't actually test this, but it should be simple enough to spot any obvious mistakes, I think.
Have node include an event that says when it is done. It is considered done when all of its children are considered done. If it has nothing to expand, it is done at the end of the server call. Otherwise, each time a child says it's done, check to see if there are any pending. Something like this:
<aura:component>
<aura:attribute name="level" type="Integer" />
<aura:attribute name="children" type="List" access="private" />
<aura:attribute name="counter" type="Integer" default="0" />
<aura:handler name="init" value="{!this}" action="{!c.createChildren}"/>
<aura:registerEvent name="done" type="c:genericEvent" />
<li>
Level {!v.level}
<ul>
<aura:iteration items="{!v.children}" var="child">
<c:node level="{!v.level - 1}" done="{!c.check}" />
</aura:iteration>
</ul>
</li>
</aura:component>
({
createChildren : function(component, event, helper) {
var level = component.get('v.level'),
children = ;
for (var i = 0; i < level; i++) {
children.push({});
}
component.set("v.children", children);
if(!children.length) {
component.getEvent("done").fire();
}
},
check: function(component, event, helper) {
component.set("v.counter", 1 + component.get("v.counter"));
if(component.get("v.counter") === component.get("v.children").length) {
component.getEvent("done").fire();
}
}
})
The application just listens for that event, too:
<aura:application>
<ul>
<c:node level="3" done="{!c.nodesLoaded}" />
</ul>
</aura:application>
N.B. I didn't actually test this, but it should be simple enough to spot any obvious mistakes, I think.
answered 1 hour ago
sfdcfoxsfdcfox
250k11193431
250k11193431
Wow. I've been on this all day!
– jmrjulian
31 mins ago
add a comment |
Wow. I've been on this all day!
– jmrjulian
31 mins ago
Wow. I've been on this all day!
– jmrjulian
31 mins ago
Wow. I've been on this all day!
– jmrjulian
31 mins ago
add a comment |
Your situation is tricky but if you know how many component will be created then you can tell the tree is fully loaded. You need to have a variable at root level which will tell you the total component count.
Each child component should speak with their parent after it is loaded, assuming parent node is loading and then child node is loading. Use below out of the box event along with custom event to communicate with parent.
<aura:handler name="render" value="{!this}" action="{!c.onRender}"/>
Any reason lightning tree cannot be used. If the JSON is not that big you can keep appending it.
add a comment |
Your situation is tricky but if you know how many component will be created then you can tell the tree is fully loaded. You need to have a variable at root level which will tell you the total component count.
Each child component should speak with their parent after it is loaded, assuming parent node is loading and then child node is loading. Use below out of the box event along with custom event to communicate with parent.
<aura:handler name="render" value="{!this}" action="{!c.onRender}"/>
Any reason lightning tree cannot be used. If the JSON is not that big you can keep appending it.
add a comment |
Your situation is tricky but if you know how many component will be created then you can tell the tree is fully loaded. You need to have a variable at root level which will tell you the total component count.
Each child component should speak with their parent after it is loaded, assuming parent node is loading and then child node is loading. Use below out of the box event along with custom event to communicate with parent.
<aura:handler name="render" value="{!this}" action="{!c.onRender}"/>
Any reason lightning tree cannot be used. If the JSON is not that big you can keep appending it.
Your situation is tricky but if you know how many component will be created then you can tell the tree is fully loaded. You need to have a variable at root level which will tell you the total component count.
Each child component should speak with their parent after it is loaded, assuming parent node is loading and then child node is loading. Use below out of the box event along with custom event to communicate with parent.
<aura:handler name="render" value="{!this}" action="{!c.onRender}"/>
Any reason lightning tree cannot be used. If the JSON is not that big you can keep appending it.
answered 1 hour ago
Avijit ChakrabortyAvijit Chakraborty
1,2151515
1,2151515
add a comment |
add a comment |
Thanks for contributing an answer to Salesforce Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f247064%2frecursive-lightning-component-how-to-know-when-its-fully-rendered%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown