Instance Manager
import InstanceMgr from '@bbc/front-end-kit/js/managers/InstanceMgr';
This manager helps to manage the many instances that may be tracked accross the project. It does so by grouping them by key (defined by the developer) and wrapping reocurring logic into neat little functions.
Getting started
To get started, initialize the instance of the manager like so
const instances = new InstanceMgr();
This is enough to start initializing instances.
API
constructor(args = {})
The constructor sets up the map internally where the instances will be stored. It sets the base parent node to the body of the page if $parentNode is not provided.
Parameters
args: the configuration object the constructor uses to initialize$parentNode: The parent node to use when selectors need to look for DOM elements to initialize (default:document.body)
Methods
add (key, ...instances)
Adds an instance to an array that is stored behind a given key in the instances map.
Parameters
key: Key to save the instance ininstances: Spread operator that will treat all the given parameters as instances to save under the givenkey
init (key, Class)
init (key, Class, params = {})
init (key, selector = null, Class)
init (key, selector = null, Class, params = {})
Initializes an instance using the given Class and adds it to the given key in the Instances map When a selector is provided as string, it will create an instance for every occurence of the DOM element. The Dom element will always be added as the $el property of the configuration object that is passed to the constructor. When params is provided, it wll merge the contents of the params object with the configuration object that is passed to the constructor. Params may also be a function that will be executed to generate a params object. In case it has to initialise a component, it will receive the $el as a property of the object it receives as parameter
This method replaces the following logic in case we'd initialise all the popups without help of the InstanceManager
const $popups = Array.from(document.querySelectorAll('.popups')).map($popupEl => {
return new Popup({
$el: $popupEl
})
})
Parameters
key: Key to save the instance inselector: The selector that will be used to perform lookups in the DOM. Every Node that is found will initialise a new Class, the node will be passed as $el property of the constructor object in the constructor.Class: The Class definition to use during initialisationparams: The object to pass to the constructor when it is initialised. May be a function that will be run for each new instance. Ifselectoris used and a method is passed, the method will receive the DOM elment that it will be passing to the class as a the $el property of the parameter object.
// init popups
instances.init('popups', '.popup', Popup);
// init tabs but process the constructor object before it is passed to the Tab constructor
instances.init('tabs', '[data-custom-tab]', Tab, (args) => {
// do something...
return {
$el: args.$el
}
}
get (key, asArray = false)
Returns the instances stored under the given key. Returns an Array instead of a Set when asArray is set to true.
Parameters
key: Key of instances to return.asArray: Whentrue, returns the instances as an Array instead of a Set.
Return
Returns a Set or Array of instances. Returns an empty Set if the key does not exist.
find (key, processor)
Look for a specific instance that is saved under a given key. The processor is a function that will be used to find the instance that is looked for.
Known bug
The source calls this._instances.get(key, true) internally, but Map.get() only accepts one argument — the second arg is silently ignored and a Set is returned. Set has no .find() method, so calling find() with a string key will throw a TypeError. Use get(key, true) and then call .find() on the resulting Array as a workaround.
// workaround
const mobileNavPopUp = instances.get('popups', true).find(instance => {
return instance.$el.classList.contains('--mobile-nav')
});
Return
The instance it found (when the bug is fixed), or a TypeError in the current source.
filter (key, processor)
Look for a specific instance that is saved under a given key. The processor is a function that will be used to filter the instance that is looked for.
Known bug
Same issue as find() — calls Map.get(key, true) which ignores the second arg and returns a Set. Set has no .filter() method, causing a TypeError. Use get(key, true) and call .filter() on the Array as a workaround.
Parameters
key: Key of map to search intoprocessor: The method that will be used for processing during the search. It works likeArray.filter()
// filter a popups that are instances of a certain custom popup (that probably extends from Popup)
const customPopups = instances.filter('popups', instance => {
return instance instanceof CustomPopup
});
Parameters
key: Key of map to filter onprocessor: The method that will be used for processing during the filtering. It works likeArray.filter()
Return
An Array of instances it found.
has (key)
Checks if the given key exists in the instance map
Parameters
key: Key to check in the instances map.
Return
Boolean (true if exists and has a list of items, may be empty)
run (keys, prop, ...args)
Edits a property or runs a method of all the instances that can be found under the given key(s) in the instances map.
Parameters
keys: Single string or array of strings that will be used as keys to filter the instances onprop: The prop that needs to be edited or run (if it is a method). May also be an object with key/value pairs to edit mutliple properties at once.args: Value that will be set on property or set of parameters that will be applied when the given method is called (spread parameter)
// will run the hide methods of all instances under the "popup" key
instances.run('popups', 'hide');
// will run the hide method with all instances under the "popup" key by passing the "true" value as the parameter for the hide method
instances.run('popups', 'hide', true)
// sets mobile property to true on all instances under the "carousel" key
instances.run('carousels', 'mobile', true)
// different way of doing the same on multiple keys and for multiple properties at once
this.instances.run([
'popups',
'carousels'
], { mobile: true });
Return
undefined
destroy(value = null)
Destroys either instances in the instance map and/or itself entirely. Very handy when handling vieport size changes that may cause the need to toggle between Mobile and Desktop versions of the project.
Parameters
value: tells thedestroymethod what to do.null: Clears the instance maptrue: Clears the instance map and destroys all the instances in it along the way by running theirdestroymethod if presentstring: Clear, remove and destroy all instances on the key that matches the given string.array: Clear, remove and destroy all the instance on the keys that matches the strings in the given array.
instances.destroy([
'popups',
'carousels'
])
Return
undefined
Getters & Setters
instances
Returns the instances as a new Iterator
entries
Returns the instances as an entries array where property and value are paired in an array
keys
Returns all the registered keys in the instances map as iterator
Private properties
The InstanceManager class uses some private properties that will be present in the scope of your app class but aren't really meant to be accessed directly.
_instances
The Map that will contain all the registered instances by key. Every key will contain a Set to save the instances in.
_$parentNode
The HTML node that will be used to perform lookups into. Defaults to document.body but may be another deeply nested element.