Controllers
Open Cells puts its functionality to handle channels and state inside reactive controllers. Controllers are a way to bundle state and behavior related to a feature. You can learn more about controllers in Lit's documentation.
These controllers are:
- ElementController: It has methods for publishing and subscribing to channels, as for navigating to pages.
- PageController: It adds all methods that has ElementController plus hooks for handling entering and leaving pages.
ElementController
Permalink to “ElementController”This controller provides the core methods from Open Cells that allow you to manage application state (through the use of channels) and to interact with Open Cells router.
To use the ElementController just follow these steps:
- Import ElementController.
import {ElementController} from '@open-cells/element-controller';
- In your component´s constructor create an instance of ElementController passing the component instance (
this
) as an argument.
class MyComponent extends LitElement {
constructor() {
super();
this.elementController = new ElementController(this);
}
}
Now the component becomes a host for the ElementController and that way the controller receives lifecycle callbacks from the component while the component can execute the API provided by the ElementController.
Note that our component extends from
LitElement
. This is required because LitElement implements the reactive controller pattern, otherwise you should implement it.
- Use the methods provided by ElementController.
this.elementController.publish('ch_user_info', data);
State
Permalink to “State”subscribe(channelName: string, callback: Function)
Permalink to “subscribe(channelName: string, callback: Function)”Subscribes to the channel named channelName
and executes the given callback
function when it reacts to state change. If there is no channel with name channelName
, then it is created.
import {ElementController} from '@open-cells/element-controller';
class MyComponent extends LitElement {
constructor() {
super();
this.elementController = new ElementController(this);
this._handleConnections();
}
_handleConnections() {
// subscribe to ch_user channel and executes _updateUserData with given channel value when channel state mutates.
this.elementController.subscribe('ch_user', (userList : Array<User>) =>
this._updateUserData(userList)
);
}
_updateUserData(userList) {
...
}
}
unsubscribe(channelName: string)
Permalink to “unsubscribe(channelName: string)”Unsubscribes from the given channel.
publish(channelName: string, value: Object)
Permalink to “publish(channelName: string, value: Object)”Publishes a value to a channel named channelName
. If there is no channel with name channelName
, then it is created.
publishOn(channelName: string , htmlElement: HTMLElement, eventName: string)
Permalink to “publishOn(channelName: string , htmlElement: HTMLElement, eventName: string)”Automatically publishes on the channel named channelName
the payload from event of type eventName
dispatched by htmlElement
. If there is no channel with name channelName
, then it is created.
import {ElementController} from '@open-cells/element-controller';
class MyDataComponent extends LitElement {
constructor() {
super();
this.elementController = new ElementController(this);
this._handleConnections();
}
_handleConnections() {
// 'change' event payload will be stored in 'ch_user' channel.
this.publishOn('ch_user', this.userInput, 'change');
}
}
See Channels for more information on how channels work.
Routing
Permalink to “Routing”navigate(pageName: string, params: Object)
Permalink to “navigate(pageName: string, params: Object)”Navigates to the route that is associated with the page named pageName
. Params are optional and are given as an object with key-value format.
backStep()
Permalink to “backStep()”Navigates to the last page visited.
getCurrentRoute(): Object
Permalink to “getCurrentRoute(): Object”Returns an object with the current route information.
getInterceptorContext(): Object
Permalink to “getInterceptorContext(): Object”Get the context object that has the Router Interceptor.
setInterceptorContext(context: Object)
Permalink to “setInterceptorContext(context: Object)”Set a new context object for the Router Interceptor.
updateInterceptorContext(context: Object)
Permalink to “updateInterceptorContext(context: Object)”Update the Router Interceptor context.
resetInterceptorContext()
Permalink to “resetInterceptorContext()”Reset the Router Interceptor context (set an empty object {}).
For more detailed information on routing see:
PageController
Permalink to “PageController”This controller provides the same functionality that ElementController
offers (described above) plus hooks to control page lifecycle: onPageEnter
and onPageLeave
. These two hooks ease the implementation of custom logic that is a common requirement on pages.
If the page implements the methods onPageEnter
and onPageLeave
, PageController will execute them.
Hooks
Permalink to “Hooks”onPageEnter()
Permalink to “onPageEnter()”Executed by PageController each time the route changes and the page enters into view.
import {html, LitElement} from 'lit';
import {PageController} from '@open-cells/page-controller';
import {customElement} from 'lit/decorators.js';
@customElement('favorite-recipes-page')
export class FavoriteRecipesPage extends LitElement {
pageController = new PageController(this);
onPageEnter() {
// custom logic to be executed each time the page enters into view like fetching the data
}
}
onPageLeave()
Permalink to “onPageLeave()”Executed by PageController each time the route changes and the current page leaves the view disappearing.
import {html, LitElement} from 'lit';
import {PageController} from '@open-cells/page-controller';
import {customElement} from 'lit/decorators.js';
@customElement('favorite-recipes-page')
export class FavoriteRecipesPage extends LitElement {
pageController = new PageController(this);
onPageLeave() {
// custom logic to be executed each time before leaving the view like "cleaning" the page
}
}