Saving State
Youโve build a marvellous app, configured your layout and the user arranged things just the way he likes. Great!
But the next time he opens the app he wants to find everything just the way he left it. Or (if youโre feeling fancy) choose from a number of saved layouts.
Strelit Layout offers a powerful persistence mechanism for that. Not only every aspect of the layout, also the state of the components within it can be converted into a serialisable object that can be saved to a database, to local storage or wherever else your heart desires.
Hereโs how it works:
Creating the layout
For this tutorial we'll use the layout created in getting-started.
var config = {
content: [{
type: 'row',
content:[{
type: 'component',
componentName: 'testComponent',
componentState: { label: 'A' }
},{
type: 'column',
content:[{
type: 'component',
componentName: 'testComponent',
componentState: { label: 'B' }
},{
type: 'component',
componentName: 'testComponent',
componentState: { label: 'C' }
}]
}]
}]
};
var myLayout = new StrelitLayout( config );
Listening for state changes
Your layout instance and all the items within it emit events. These bubble up, just like
DOM events. The event we're interested in at the moment is called
stateChanged. It is emitted whenever something happens that modifies the
saveable layout state. Listening to it works like this:
myLayout.on( 'stateChanged', function(){
//now save the state
});
The actual state object is created by calling myLayout.toConfig();. For our
example we'll store it in the browser's localStorage.
myLayout.on( 'stateChanged', function(){
var state = JSON.stringify( myLayout.toConfig() );
localStorage.setItem( 'savedState', state );
});
myLayout.toConfig() explicitly rather
than just getting the new state as a parameter of the
stateChanged callback. This is because serialisinging entire layouts can be
expensive - and stateChanged will fire a lot. It might therefor be a good
idea to 'debounce' your state save calls or offer a save-button, depending on
your performance requirements.
Creating Layouts from saved states
So now the next time the user opens the app there's a choice. Either he has used it before and the app's state is stored in localStorage or he's using it for the first time and we provide a default config.
var myLayout,
savedState = localStorage.getItem( 'savedState' );
if( savedState !== null ) {
myLayout = new StrelitLayout( JSON.parse( savedState ) );
} else {
myLayout = new StrelitLayout( config );
}
Saving Component States
So far we've only saved the layout's state, but what about the components within
it, the ones you've build? Well, remember the
componentState: { label: 'C' } entry that you've configured?
This is just the initial state, the component itself can update it by calling
container.extendState( state ); or
container.setState( state );.
This stores it and emits a stateChanged event that bubbles up to the layout
manager.
Let's update our testComponent to show a text input with a persistant value:
myLayout.registerComponent( 'testComponent', function( container, state ){
// Create the input
var input = $( '<input type="text" />' );
// Set the initial / saved state
if( state.label ) {
input.val( state.label );
}
// Store state updates
input.on( 'change', function(){
container.extendState({
label: input.val()
});
});
// Append it to the DOM
container.getElement().append( input );
});
And initialise the layout
myLayout.init();
The result
Interactive Example: Saving State
Inspect, fork, and test this complete layout implementation live on CodePen:
Community & Support
Need help or have architectural questions?
Whether you are building complex multi-screen trading terminals, enterprise data workspaces, or migrating from legacy layout engines, the Strelit UI Kit engineering team and community are here to help.
Open an Issue on GitHub โ