SLB: Notes – JS: Component References
Requirements
- Unified way to get/set component references from within other components
- Used as base of other get/set methods (
get_viewer()
, etc.) - Smart – not too dependent on configuration
- Safe – manages component data without risk of corruption
Get component reference (Process)
Arguments
- Property name (
string
): Name of property to retrieve (group
,viewer
, etc.) - Data type
(
Component Class [function]
): Component type (View.Viewer
,View.Group
, etc.) - Validates data type before returning data
- Enables creation of new component instance if necessary
- Get default (optional) (
boolean
): Whether to get default component reference from controller - Default: Yes
- Useful when searching through container components for reference (as returning default reference will stop iteration through containers)
Prioritized search for component
- Check if instance property already set
- Can be set by various operations
- Previous property retrieval (caches property for future access)
- Direct property setting (e.g.
set_viewer()
, etc.) - Return value immediately if property is set
- Check instance attributes for component
- Instance attributes stored as
:
instance.attributes
(object
) - Attribute key matches property name:
instance.attributes.viewer
will containviewer
reference - Possible return values – Dependent on how attribute was set
- String: ID of component reference
- Components stored by ID in controller (
View
) - Object reference: Direct reference to another component
- Set attribute value to main instance property if found (for faster future retrievals)
set_component(property_name, value)
- Sanitizes value
- Retrieves actual component reference from controller based on ID (
string
) and component type - Check containers
- Containers: Component instances that current component instance can inherit/access properties from
- Such components contain current component (e.g.
Group
containsItem
, etc.) - Containers defined in component class definitions (
object
) - Key: property name (
group
,viewer
, etc.) - Value: Component data type (
View.Group
,View.Viewer
, etc.) - Iterate through containers
- Retrieve container component reference
//Example (Group) var container = get_component('group', View.Group);
-
Recursion issue inget_component()
if usingget_component()
to retrieve containers- Example: Property being searched for = Container being searched
- Property: group
- Current container: group
A
: Skip containers that match current property being searched for- e.g. Don’t look in ‘group’ container if attempting to retrieve ‘group’ reference
- Look for component reference in valid containers
var component = container.get_component(property_name, data_type);
- Containers will generally access controller object (
View
) if reference not set on container itself (next step) ?
What if subsequent containers have component reference directly?- Example:
group
container does not have reference, butview
container does - Options
- Retrieve reference from container’s controller as fallback (current)
- Only single container will be evaluated (since a valid reference will be returned from controller as fallback)
-
Subsequent containers will not have a chance to retrieve reference-
Pointless to have multiple containers- Do not use controller as fallback
- Add additional parameter to
get_component()
to skip fallbackvar container = get_component('group', View.Group, false);
- Return empty value if reference not found on component itself
+
All containers will be evaluated- Get reference to default component from controller
- Controller (
View
) is set as parent of all components - Default component created if not previously created
- Uses initialization options to build component instance with default properties
?
Do all components have a default?- Viewer: Yes
- Theme: Yes
- Group: No
?
Handling items without groups- Ungrouped items are displayed singly (current)
- No slideshow support for ungrouped items
+
Clear/straightforward operation+
Server-side can add ungrouped items to group based on options (group by post, etc.)- Display ungrouped items as group
- Use a default group to group all items not explicitly placed in a group
- Ungrouped items will be displayed as a slideshow
+
Possible to easily cycle through ungrouped items-
Overrides admin options-
Items do not need to be grouped if they were not purposefully grouped-
Items that you want to display in isolation will need to have to be explicitly placed in their own group- Content Item: No
- All content items are unique and should point to valid content
- Content Type: No
- All content types registered manually
Return value
- Valid component type or
NULL
(e.g. if component reference not found) - Wrapper methods (
get_group()
,get_viewer()
, etc.) can use return value to validate data and return appropriate value
Set component reference (process)
Arguments
- Property name (
string
): Name of property to set (group
,viewer
, etc.) - Value (
object|string
): Component reference string
: ID of reference – stored in controller (View
)object
: Component instance reference- Data type
(
Component Class [function]
): Component type (View.Viewer
,View.Group
, etc.) - Required data type for component
Methodology
- Retrieve component instance from controller if ID supplied
var component = this.get_parent().get_component(id, data_type);
?
What to do if component with matching ID does not exist in controller?A
: Options- Return empty value (
null
) - Component reference not set on current object
- Continue to next step (container iteration) if attempting to set invalid value in
get_component()
to find valid component reference - Create new component
- Use supplied ID to initialize new component instance
- Use controller defaults/options to set new component’s properties
- Controller options are parsed (if not already parsed) to provide access to component-specific options/properties
?
Use single method to initialize new components or use component-specific methods?A
: Options- Single universal method
- Controller properties will need to parsed into groups so that new component will be passed appropriate values
+
Only one method to maintain when API changes, etc.+
Components share same base definition (methods, properties, etc.)-
Single method may become convoluted when components diverge a lot- Component-specific methods
- Create specific method for initializing each component (
View.add_group()
, etc.) +
These methods should exist anyway for adding components directly?
How to add components if component-specific method does not exist- Component-specific + Universal method
- Use universal method (less specialized) if component-specific (more specialized) initialization method for component does not exist
+
Simple components may not need specialized methods+
Allows more specialized creation of components as needed+
Object’s attributes say that component should exist+
Not overwriting anything – only creates new instance if ID does not exist- Can customize component instance properties later if necessary
- New component instance saved to appropriate controller collection (Based on data type:
View.groups
,View.viewers
, etc.) - Save component reference to specified property type
this.property = component;