X

Technical Articles relating to Oracle Development Tools and Frameworks

  • JET
    February 1, 2017

JET Custom Components VII - The Lifecycle

Duncan Mills
Architect

Last Updated Jan 2020 for JET 8

Introduction

Once you get into any serious usage of JET Custom Components it becomes useful to understand the lifecycle of any component in some detail, this is particularly true if, for example, your components UI needs to be dynamically adjusted at runtime. Fortunately the lifecycle is simple to understand and work with, although, as we will see it has changed over time.  

The Complete Lifecycle

In the following table I outline all of the events and lifecycle methods that can be called, within your component viewModel, as a Custom Component is rendered in a view. Note that all of the methods mentioned are optional, you don't need to create them for the component to work (with the exception of the basic Constructor for the object of course).

Note that this table has been updated as of JET 8.0.0 and deprecated events and lifecycle methods have a strikethough and an explanation as to what to use instead

1 Constructor called  The component viewModel constructor will be passed a context object (see below)
2 activated lifecycle method executed
The activated lifecycle method is called and passed the standard context object. At the point in time that this method executes, the base component element will exist in the HTML DOM, however it will not yet have any child nodes1 so you cannot manipulate the UI at this stage.
You can return a promise from this method which will delay the rest of the component initialisation until it is complete.

 
attached lifecycle method executed
The attached lifecycle method is called and passed the standard context object. At this phase, the view defined by the Composite Component bootstrap script will have been processed and the Composite Component element will now have child elements in the DOM that you can locate and manipulate if necessary. If you need to set up any viewModel values that will be used by knockout bindings in the generated view, this is your last chance to do so. Replaced by the connected method
3 connected lifecycle method executed
The connected lifecycle method is called and passed the standard context object. At this phase, the view defined by the Composite Component bootstrap script will have been processed and the Composite Component element will now have child elements in the DOM that you can locate and manipulate if necessary. If you need to set up any viewModel values that will be used by knockout bindings in the generated view, this is your last chance to do so. Unlike the deprecated attached method, this method is called every time that the element is connected to the DOM, not just the first time
4 bindingsApplied lifecycle method executed
The bindingsApplied lifecycle method is called and passed the standard context object. At this phase, the Knockout applyBindings has been called on the subtree and any data-bind or other Knockout directives will have been applied. Thus it would be too late to change a DOM element to add a data-bind at this stage.

 
dispose lifecycle method executed


As a module containing this Composite Component is being replaced, this dispose lifecycle method is called with a reference to the Composite element object. This gives you the opportunity to do clean up if required. Note that dispose does not get called if the user resets the page with a manual browser refresh or explicit navigation that does not first replace the current module. Therefore, you cannot rely on this method as the only way of releasing resources. Replaced by the disconnected method.

5 disconnected lifecycle method executed
The disconnected lifecycle method is called with a reference to the Composite element object every time the component is detached from the browser DOM. This gives you the opportunity to do clean up if required (esp. any listeners that the component may have registered).

As well as these lifecycle methods and events, you can also receive property-changed events throughout the lifetime of the component via the propertyChanged() callback that we covered in Article IV.

The context Object

As shown above, most of the lifecycle objects (except disconnected), as well as the viewModel constructor are passed a common context object. This object contains the following properties:

  1. element - the DOM element that represents the JET Custom Component itself. Useful if you want to attach listeners (such as property-change listeners) or to manipulate the DOM subtree for the component.
  2. properties - An object which gives access to the map of properties that have been passed into the component. Again see Part IV in this series for information on its usage. Generally I'd recommend storing the map reference on the component viewModel as soon as you can2. This will ease later access in event handlers, methods and so forth. However, for the purpose of accessing properties in one of the startup lifecycle phases, always use this pops promise that you obtain from the context i.e. using context.props.then(). That will ensure that you're not caught out by assuming that a stored reference has already been resolved during an earlier stage in the lifecycle.
  3. slotCounts - An object containing keys for each slot in the component and the number of nodes assigned to those slots. We cover the slotting feature in Parts VIII and IX of this series.
  4. unique - A string value generated by the framework which will return a unique "identity" for the Composite Component. This identity will take the form of _ojcomposite0 where the trailing number increments for each composite in the view. This value is also available for direct reference in your view using $unique. Note, although this composite identity will be unique within the parent view that embeds the custom component, the generation is not idempotent and the unique identity that is provided for a particular instance of a component might change from run to run of a view. As such, the unique value is useful for ensuring unique ids within an instance of a CCA. For a more stable unique identity that will not change from run to run, you could consider assigning an id to the custom  component instance in the consuming view. You can then use the following uniqueID attribute for a stable identity
  5. uniqueId - A variant of the unique attribute, uniqueid will either contain the specific element ID assigned by the user to the custom component element, or, if that has not been set, then the same value as the unique attribute. In we recommend the use of uniqueId over unique because of the option for ID stability.  Your component view can directly access uniqueId via the built-in $uniqueId variable

Connected and Disconnected

The connected and disconnected events are slightly special in two ways: 

First of all they are paired, in that for each connected call you will also at some point get a disconnected call.  This is useful if you need to do something such as add a listener to the document as a whole; you can add it on connected and then remove it to clean up again in disconnected. 

Secondly, these methods may be called multiple times throughout the lifespan of a component instance, all depending on where the component is and how it is being used. (For example if the component was in a pop-up dialog). Be aware of this and take care that you do not carry out any expensive operations in either of these lifecycle callbacks.

(Deprecated) Lifecycle Method Name Customization

In versions of JET prior to 3.0 it is possible to override the lifecycle function names used by the lifecycle callbacks (bindingsApplied, activate and so forth). This was accomplished by updating the defaults property of oj.Composite. This feature has been deprecated and should not be used, changing these values would make your CCAs incompatible with every other application that does not use the same names which defeats the whole object of a component standard. It goes without saying that you should not use this capability.

What I've Not Covered

This article is covers the basic custom component lifecycle. There are two related further topics that will be discussed in later articles in this series:

  1. Custom Property Parsing
  2. The use of promises during registration (now deprecated)

What's Next?

In this article we encountered the slotCount property of the lifecycle context object. Therefore it makes sense to take a look next at very powerful feature of the Web Components / Composite Component Architecture - slotting.


JET Custom Component Series

If you've just arrived at JET Custom Components and would like to learn more, then you can access the whole series of articles on the topic from the Custom JET Component Learning Path


1 This is not strictly true in the case where you are using slotting, something I cover in the next couple of articles. However, that's not to say that you therefore have free reign to go playing with the DOM nodes at this stage in the lifecycle, you probably shouldn't!

Be the first to comment

Comments ( 0 )
Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.