4

So, I'm building a custom process in SF using custom lightning components (most of my experience is in VF and Apex). The process is kicked off from a button on a lightning page, and my initial component implements force:lightningQuickActionWithoutHeader, and opens in a modal popup.

My desire is for some displayed records to be selected within this modal, then the user hits the 'Next' button, which opens a new page in a new tab. The user would then proceed to go through several more steps on this new page, hitting the 'next' button each time, but all the remaining steps happen within this new tab.

What would an appropriate approach to this be? Should I make a new lightning component for the new page, complete with its own controller, etc? Would it make more sense to have a single component handle the modal, the new tab and the 'next' button actions, then make separate components to drop into that one for each step? Is it even possible to use a single component for both a modal popup and a new tab page?

I guess I ask because it seems strange to me to need different components for every step of a process that's using/manipulating the same set of data, just to be able to set up the UI a certain way.

5

The beautiful part about Lightning is that you're allowed to separate the main logic from the UI in various ways, and reuse the parts you like as you'd like. For example, in a multistep wizard, your main component might look like this:

<aura:component controller="ABCController">
  <aura:attribute name="record" type="Map" default="{}" />
  <aura:attribute name="page" type="Integer" default="1" />
  <aura:attribute name="content" type="Aura.Component[]" default="[]" />

  {!v.content}

  <ui:button disabled="{!v.page eq 1}" label="Previous" action="{!c.goBack}" />
  <ui:button disabled="{!v.page eq 7}" label="Next" action="{!c.goNext}" />
  <ui:button disabled="{!v.page ne 7}" label="Finish" action="{!c.finish}" />
</aura:component>

At this point, you can specify the content that should be currently displayed by using $A.createComponents:

$A.createComponents(
  [["c:wizardContentPage1", { record: component.getReference("v.record") }]],
  function(components) {
    component.set("v.content", components);
  }
);

Most likely, the setup would be more complicated, as you might need to arrange for an event, validation, etc, but the main trick here is Aura.Component[]. Using this technique, you can keep the majority of the UI in separate components for legibility, and those can have extended controllers that do other things, and you can communicate with the main component via events.

As far as reusing the same component in a page, it's simply a matter of putting that component into an app:

<aura:application extends="force:slds">
  <aura:attribute name="id" type="String" access="global" />
  <c:mainComponent recordId="{!v.id}" />
</aura:application>

Which you provide the record Id just like in Visualforce:

/c/wizard.app?id=0012...

The application automatically parses the query string and puts the values into exposed attributes.

Without knowing the full scope of what you're trying to do, this advice is pretty generic, but the main takeaway is that it is possible to arrange for most of the logic to be kept in a single component, and move the UI into a separate component (or as many as you need).

As far as best practices go, you should be aiming to build reusable components as much as possible. UI elements, for example, can often be decomposed into smaller components that can be reused frequently. Don't worry too much about getting it "just right," just try to make the code reasonably legible (e.g. if your component is 2,000 lines big, it's probably too big) and reasonable practical.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.