Right, looks like you're right about the menuItem
var not being available until some magic happens. A consistent way around this would be to check that v.menuItems
is a length greater than 0 in the rerender
method, so something like
rerender: function(component, helper) {
var menuItems = component.get('v.menuItems');
if (menuItems.length > 0) {
//you're good to go with external JS DOM shenanigans
}
this.superRerender();
}
At this point it's reasonable to assume that:
- External JS dependencies have been fully loaded
- menuItems is populated
- The navigation menu is 'ready' on the DOM
The 'dirty' part is where you have to call back to your external JS from Lightning- so you'll probably have to bind a function to the window.
Not to deviate too much from the original question- but this is the best way to work with external JS that requires the DOM to be 'ready'- have Lightning call a function on the window.
--- Edit for visibility ---
As mentioned in my comment below, I've tested the exact case on a Community, and confirmed that rerender
is RELIABLY called when menuItems is populated from within a Community context, when implemented following the instructions.
Anyway:
rerender
is called after menuItems
is populated. There is no disputing this fact. This meets your use case of needing to reliably interact with the DOM when it's "ready".
In the initial part of your question, I noted that you had a variable in the Extension
component that was local to it- and you were expecting a rerender
to be called once GetHelloWorld
initialises.
Unless you link the variable using the same parameter syntax as you do for the Composition
component- it will remain LOCAL to the component. It doesn't get touched by ANY of your other components. It's not going to rerender
.
--- Second edit ---
Well, looks like I got owned by Lightning, very very frightening again.
So- ignore everything I wrote above- here's what's happening:
rerender
isn't called by default- I think the reason it was calling it on my org is due to the CSS classes being loaded via ltng:require
.
v.menuItems
isn't reliably populated even if rerender
is called (I refreshed the page 2-3 times prior to writing the first edit, and walked off triumphant)
- The
valueChange
event is useless because there's no render
type event to signal that the menu is in the DOM
- Lightning is horrible
Apologies if I got the wrong end of the stick earlier- it looks like you're plum out of luck if you're looking for a clean solution to manipulate the navigation menu post render. Suggest maybe using click event or CSS to achieve said effects?
What you need here is the appropriate SLDS class to be able to render your list items horizontally.
Add the Horizontal List SLDS class where you are rendering your list, and that should work. Your code should look like as below.
<ul class="slds-list_horizontal" onclick="{!c.onClick}">
....
</ul>
A sample code and its output for reference.
<ul class="slds-list_horizontal">
<li>Menu1 </li>
<li>Menu2 </li>
<li>Menu3 </li>
</ul>
Best Answer
I have answered with a solution to a similar question with the same goal here: https://salesforce.stackexchange.com/a/289509/77440
In summary, there is an undocumented attribute called navigationLinkSetId where you can specify either the Id or developer name of the Navigation Link Set you have created through Community Builder (Settings > Navigation). Adding this attribute with a default value of the Id/developer name of the desired navigation menu will render the corresponding navigation menu items instead of the Default Navigation.
Find the Id or developer name of your navigation menu using SOQL:
SELECT Id, DeveloperName, MasterLabel FROM NavigationLinkSet
Add the attribute to your component that extends forceCommunity:navigationMenuBase:
<aura:attribute name="navigationLinkSetId" type="String" default="My_Custom_Navigation" />
Please find the details of the full solution in the linked answer.