UnmanagedComponent
cdf.components. UnmanagedComponent
The UnmanagedComponent is an advanced version of the BaseComponent which allows control over the core CDF lifecycle for implementing components.
It should be used as the base class for all components which desire to implement an asynchronous lifecycle, as CDF cannot otherwise ensure that the postExecution callback is correctly handled.
CDF Async Developer's Guide
CDF now supports proper, asynchronous, AJAX calls for all its querying. The following is a guide to converting old components and dashboards to the new async style, and developing new ones based on asynchronous querying.
Rationale
The first step to understanding the changes in the async patch is understanding the CDF component lifecycle. When a component is updated, the basic update lifecycle looks like this:
preExecution -> update -> postExecution
Usually, though, there will be a call to a data source, with a subsequent call to postFetch, and only then is the component rendered:
preExecution -> update -> query -> postFetch -> redraw -> postExecution
This is a more typical lifecycle, and one that has some important limitations. First, preExecution and postExecution are entirely the responsibility of CDF itself, rather than the component. Because CDF has no control over the contents of the update method, it has no way of ensuring that, should the component execute an asynchronous query, postExecution only runs after redraw. In this case, you are likely to see this instead:
preExecution -> update -> postExecution -> query -> postFetch -> redraw
This breaks the contract for postExecution running after the component is done updating. The solution here is that the component itself must take control of postExecution, while keeping the burden of implementing the lifecycle in CDF rather than passing it to the component developer. On a related topic, postFetch has become a de facto standard part of the lifecycle, yet its implementation was left to the component implementers, which leads to a fairly large amount of boilerplate code.
Our objective here was to retool the base component to deal with both of these issues, thus allowing queries to be performed asynchronously while reducing the developer effort involved in creating a component.
Component Execution Order and Priority
There are no major changes in the way components behave. There is, however an important caveat: since all components that have been converted will be executed simultaneously, we can no longer rely on the order of execution.
There's now an additional property named priority. This is the priority of component execution, defaulting to 5. The lower the number, the higher priority the component has. Components with the same priority with be executed simultaneously. This property is useful in places where we need to give higher priority to filters or other components that need to be executed before other components.
This way there's no longer the need to use dummy parameters and postChange tricks to do, for instance, cascade prompts.
Backward Compatibility and Changes
Maintaining backwards compatibility requires some care. If components have no priority, we give them a sequential value, trying to emulate the old behavior. It's recommended that proper priorities are set in order to take advantage of the new improvements.
If using Community Dashboard Editor (CDE), note that if you edit a dashboard and save it, all components will have a default priority of 5. This may break the old behavior. If you need to change a dashboard, make sure you tweak the priorities, if needed.
Developing Components
Components desiring to use asynchronous queries should inherit from the new UnmanagedComponent, instead of BaseComponent. The UnmanagedComponent base class provides pre-composed methods which implement the core lifecycle for a variety of different scenarios:
synchronous: implements a synchronous lifecycle identical to the core CDF lifecycle.triggerQuery: implements a simple interface to a lifecycle built around Query objects.triggerAjax: implements a simple interface to a lifecycle built around AJAX calls.
Since all these lifecycle methods expect a callback which handles the actual component rendering, it's a conventional style to have that callback as a method of the component, called redraw. It's also considered standard practice to use Function#bind or _.bind to ensure that, inside the redraw callback, this points to the component itself.
Use synchronous If Your Component Does Not Use External Data
synchronous If Your Component Does Not Use External DataComponents that do not use any external data at all can continue subclassing BaseComponent without any change of functionality. However, for the sake of consistency (or because you want querying to be optional), you can use subclass UnmanagedComponent and use the synchronous lifecycle method to emulate BaseComponent's behavior:
If you want to pass parameters to redraw, you can pass them as an array to synchronous:
Use triggerQuery When You Want Your Component To Use CDA/Query Objects
triggerQuery When You Want Your Component To Use CDA/Query ObjectsIf you're using a CDA data source, you probably want to use triggerQuery to handle the component lifecycle for you. triggerQuery expects at a minimum a query definition and a redraw callback to process the query results. The query definition is an object of the form:
Typically, if you are using CDE, these properties will be added to one of either this.queryDefinition, this.chartDefinition or this.trafficDefinition so you can just use this pattern:
Alternating Between Static And Query-Based Data
As the lifecycle methods are completely self-contained, you can switch between them at will, deciding on an appropriate lifecycle at runtime. A common pattern (used for example in SelectComponent and the CccComponent family) is exposing a valuesArray property, and using static data if valuesArray is provided, or a query if it is not. Using UnmanagedComponent, this convention would look like this:
AMD Module
Extends
cdf.components.BaseComponent
Constructor
new UnmanagedComponent(properties)
Advanced version of the BaseComponent which allows control over the core CDF lifecycle.
Members
chartDefinition : ``object`
`function``
elapsedSinceSplit : numberProtected
Number of milliseconds since the timer split.
elapsedSinceStart : numberProtected
Number of milliseconds since the timer start.
htmlObject : stringProtected
HTML element identifier where the component is rendered.
initInstance : NumberDeprecated Protected
The Dashboard instance to which the component belongs.
isDataPush : boolean
Indicates if the component lifecycle is being run because of a data push event.
isDisposed : booleanProtected
The component is in a disposed state.
isManaged : boolean
Flag that defines if the component is managed or not.
isRunning : boolean
Flag that defines if the component is running or not.
logColor : stringProtected
Color to use while logging messages.
name : stringProtected
Name of the component.
postChange : function
Function to be executed after the components parameter value changes.
preChange : function
Function to be executed before the components parameter value changes.
priority : number
Priority of a component in the cdf execution cycle.
queryDefinition : ``object`
`function``
timerSplit : numberProtected
Start date for the timer split.
timerStart : numberProtected
Start date for the timer start.
trafficDefinition : ``object`
`function``
type : stringProtected
Type of the component.
visible : booleanProtected
Visibility flag.
Methods
_disposeCore()Protected
Override this to (irreversibly) dispose of any resources which are not disposed of when simply removed.
_setQuery(queryDef, queryOptions) : cdf.queries.BaseQueryProtected
Creates and sets the component's current query given its definition, and optionally, query options.
_throwIfDisposed()Protected
Throws an error if the Dashboard is already disposed.
_unlink()Protected
Un-links the component without releasing the resources.
beginAjax(ajaxParameters, callback)
The beginAjax lifecycle handler implements the beginning phase of a lifecycle based on generic AJAX calls.
beginExec(isDataPush) : boolean
Begins execution of the component.
beginQuery(queryDef, callback, queryOptions)
The beginQuery lifecycle handler implements the beginning phase of a lifecycle around Query objects.
block()
Trigger UI blocking while the component is updating.
callCounter() : number
Increment the call counter, so we can keep track of the order in which requests were made.
clear()
Clears the component HTML element.
clone(parameterRemap, componentRemap, htmlRemap) : cdf.components.BaseComponent
Clones a component.
copyEvents(target, events)
General copy events methods.
dispose()
Disposes this component, if it wasn't already disposed.
drawTooltip()
Draws a tooltip, if one is defined in the component options.
endExec()
Ends a successful execution of the component.
error(msg, cause)
Triggers an error event on the component.
errorNotification(err, ph)
Creates an error notification popup.
execute(callback)
Generic execute method that handles preExecution and postExecution lifecycle tasks.
failExec(arg)
Fails execution of the component, given a string, an error object or the arguments of a jQuery.ajax error callback.
focus()
Focus the first placeholder DOM element on the component.
getAddIn(slot, addIn) : cdf.AddIn
Gets an add-in for this component.
getAddInOptions(slot, addIn) : object
Gets an add-in option.
getErrorHandler() : cdf.components.UnmanagedComponent
Gets an error handler suitable for use as a jQuery.ajax error callback or a try/catch handler.
getQueryDefinition() : Object | undefined
Gets the query definition object.
getSuccessHandler(counter, success, always, canceled) : function
Builds a generic response handler which runs the success callback.
getValuesArray() : Array.<object>Deprecated
Gets the values array property.
hasAddIn(slot, addIn) : boolean
Returns true if the add-in with the provided subtype and name exists.
isSilent() : boolean
Returns true if the component's lifecycle is marked as silent.
onWillRemove()
Prepares the component for removal.
parseArray(jData, includeHeader) : Array.<object>Deprecated
Builds an array with the data received from the server in another format.
parseArrayCda(jData, includeHeader) : Array.<object>Deprecated
Builds an array with the data received.
placeholder(selector) : jQuery
Getter for the component's DOM element.
postExec()
Handles calling postExecution when it exists.
postFetchData(data) : object
Handles calling postFetch, when it exists, and triggering the postFetch event.
preExec() : boolean
Handles calling preExecution when it exists.
setAddInOptions(slot, addIn, options)
Sets the options for an add-in.
showTooltip()
Shows a tooltip attached to the component, if one is defined in the _tooltip option.
synchronous(callback, arg)
The synchronous lifecycle handler closely resembles the core CDF lifecycle.
triggerAjax(url, params, callback, ajaxParameters)
The triggerAjax lifecycle handler builds a lifecycle around generic AJAX calls.
triggerQuery(queryDef, callback, queryOptions)
The triggerQuery lifecycle handler builds a lifecycle around Query objects.
unblock()
Trigger UI unblock when the component finishes updating.
Events
cdf:error
Event triggered on error.
cdf:postExecution
Event triggered after execution.
cdf:postFetch(data)
Event triggered after fetching data.
cdf:preExecution
Event triggered before execution.
cdf:render
Event triggered after the render callback executes.
all
Event triggered by any other event.
Constructor Details
new UnmanagedComponent(properties)
The constructor of an unmanaged component.
**Source:**components/UnmanagedComponent.js, line 21
Name
Default Value
Summary
properties : object
An object with the properties to extend the UnmanagedComponent instance.
## Members Details
chartDefinition: object` | `function
The chart definition object used to hold the parameters for the query.
**Source:**components/UnmanagedComponent.js, line 237
See also:queryDefinition.
elapsedSinceSplit: numberProtected
Number of milliseconds since the timer split.
**Source:**components/BaseComponent.js, line 98
Inherited From: cdf.components.BaseComponent#elapsedSinceSplit
Default Value:-1
elapsedSinceStart: numberProtected
Number of milliseconds since the timer start.
**Source:**components/BaseComponent.js, line 108
Inherited From: cdf.components.BaseComponent#elapsedSinceStart
Default Value:-1
htmlObject: stringProtected
The HTML element identifier, unique in the HTML page, where the component is rendered.
**Source:**components/BaseComponent.js, line 46
Inherited From: cdf.components.BaseComponent#htmlObject
initInstance: NumberDeprecated Protected
The Dashboard instance to which the component belongs.
**Source:**components/BaseComponent.js, line 130
Inherited From: cdf.components.BaseComponent#initInstance
isDataPush: boolean
Indicates if the component lifecycle is being run because of a data push event..
**Source:**components/UnmanagedComponent.js, line 216
**Default Value:**false
isDisposed: booleanProtected
The component is in a disposed state.
**Source:**components/BaseComponent.js, line 128
Inherited From: cdf.components.BaseComponent#isDisposed
**Default Value:**false
isManaged: boolean
Flag that defines if the component is managed or not.
**Source:**components/UnmanagedComponent.js, line 198
**Default Value:**false
**Overrides:**cdf.components.BaseComponent#isManaged
isRunning: boolean
Flag that defines if the component is running or not.
**Source:**components/UnmanagedComponent.js, line 207
**Default Value:**false
logColor: stringProtected
Color to use while logging messages.
**Source:**components/BaseComponent.js, line 118
Inherited From: cdf.components.BaseComponent#logColor
**Default Value:**undefined
name: stringProtected
The name of the component. Its name needs to be unique in the dashboard to which they belong.
**Source:**components/BaseComponent.js, line 30
Inherited From: cdf.components.BaseComponent#name
postChange: function
Function to be executed after the components parameter value changes.
**Source:**components/BaseComponent.js, line 150
Inherited From: cdf.components.BaseComponent#postChange
preChange: function
Function to be executed before the components parameter value changes.
**Source:**components/BaseComponent.js, line 141
Inherited From: cdf.components.BaseComponent#preChange
priority: number
Priority of a component in the cdf execution cycle.
**Source:**components/UnmanagedComponent.js, line 218
**Default Value:**5
queryDefinition: object` | `function
The query definition object used to hold the parameters for the query.
**Source:**components/UnmanagedComponent.js, line 228
timerSplit: numberProtected
Start date for the timer split.
**Source:**components/BaseComponent.js, line 88
Inherited From: cdf.components.BaseComponent#timerSplit
**Default Value:**0
timerStart: numberProtected
Start date for the timer start.
**Source:**components/BaseComponent.js, line 78
Inherited From: cdf.components.BaseComponent#timerStart
**Default Value:**0
trafficDefinition: object` | `function
The traffic definition object used to hold the parameters for the query.
**Source:**components/UnmanagedComponent.js, line 247
See also:queryDefinition.
type: stringProtected
The type of the component, usually the class name of the component.
**Source:**components/BaseComponent.js, line 38
Inherited From: cdf.components.BaseComponent#type
visible: booleanProtected
Visibility flag.
**Source:**components/BaseComponent.js, line 56
Inherited From: cdf.components.BaseComponent#visible
**Default Value:**true
## Method Details
_disposeCore()Protected
Override this to (irreversibly) dispose of any resources which are not disposed of when simply removed.
**Source:**components/BaseComponent.js, line 574
Inherited From: cdf.components.BaseComponent#_disposeCore
_setQuery(queryDef, queryOptions) : cdf.queries.BaseQueryProtected
Creates and sets the component's current query given its definition, and optionally, query options.
**Source:**components/UnmanagedComponent.js, line 669
|Name|Description| |----|-----------| |`cdf.queries.BaseQuery`|The query `object`.|
Name
Default Value
Summary
queryDef : object
The query definition object.
queryOptions : objectOptional
Query options object.
Name
Default Value
Summary
ajax : objectOptional
Options passed to jQuery.ajax. The jQuery.ajax options data, url, error and success are reserved.
pageSize : numberOptional
The page size of paginated results.
_throwIfDisposed()Protected
Throws an error if the Dashboard is already disposed.
**Source:**components/BaseComponent.js, line 582
Inherited From: cdf.components.BaseComponent#_throwIfDisposed
_unlink()Protected
Un-links the component without releasing the resources.
**Source:**components/BaseComponent.js, line 561
Inherited From: cdf.components.BaseComponent#_unlink
beginAjax(ajaxParameters, callback)
The beginAjax lifecycle handler implements the beginning phase of a lifecycle based on generic AJAX calls. It implements the lifecycle:
Ending the execution is the responsibility of the specified callback, by calling endExec, resulting in:``` postExec` -> `unblock` (optional) or `failExec
``preExecution->block(optional) ->fetchData->postFetch -> callback
postExecution` -> `unblock` (optional) or `failExec
if(this.beginExec()) { try { callback.call(this); } catch(ex) { this.failExec(ex); } }
``preExecution->block(optional) ->fetchData->postFetch-> render ->postExecution->unblock (optional)
``preExecution->block(optional) ->fetchData->postFetch-> callback ->postExecution->unblock (optional)
Last updated
Was this helpful?

