Ember State Manager
An Ember.JS state management solution that is built upon the ideals of ember-state-services.
State management is one of the most complex aspects of large application design and when done wrong often leads to bugs and errors. EmberJS contains 2 high-level avenues for storing state: controllers (long-term state) and components (short-term state). Controllers are singletons and any state you set on them will stay there until your application is reloaded or you override the previous value. Components on the other hand are created and destroyed as they enter/leave the DOM and any state that is set on them will be removed/reset each time they are recreated. As you build more complex applications you will find yourself needing a way to have some sort of middle ground solution. Something that has properties of both long-term state and short-term state.
Features
- Easily handle complex state
- Access your states from anywhere via a service, template helper, or CP macro
- Ember generator to create Object, Array, Buffered Object, and Buffered Array type states
- State bucketing
Installation
ember install ember-state-manager
Helpful Links
- ### Changelog
Looking for help?
If it is a bug please open an issue on GitHub.
Setup
The first thing you will need to do is create your state file(s). All states are expected
to be under app/states
and must export an Ember (like) Object. This addon ships with
a blueprint to make this pretty easy.
ember generate state <name> <options...> Create a new state --type
# Create a state named 'foo' that is an Object ember generate state fooember generate state foo --type=object # Create a state named 'foo' that is an Array ember generate state foo --type=array # Create a state named 'foo' that is a Buffered Object Proxy (requires ember-buffered-proxy to be installed) ember generate state foo --type=buffered-object # Create a state named 'foo' that is a Buffered Array Proxy (requires ember-buffered-array-proxy to be installed) ember generate state foo --type=buffered-array
Once you run the generate command, you will see a new file has been created:
// app/states/foo.js; const State = EmberObject; State; ;
Usage
You can access a state via the provided service, template helper, or computed macro.
stateManager
Service
The This service gives you full control on accessing and deleting states.
stateFor
Method - Returns a state object for the given model with the specified state (file) name.
;
Available Options:
bucketName: String
: The bucket name to store the state under (optional)createWithoutModel: Boolean
: Whether to return a valid state object even if the model is falsy (defaulted to false).
// Example Usagethis;
deleteStateFor
Method - Delete the state object for the given model with the specified state (file) name.
Calling stateFor
after this method will return a new state object.
;
Available Options:
bucketName<String>
: The bucket name to store the state under (optional)
// Example Usagethis; // old statethis;this; // new state
{{state-for}}
Template Helper
The You can access a state in your templates via the {{state-for}}
helper which is a
proxy to stateManager.stateFor
.
{{state-for model stateName bucketName=bucketName createWithoutModel=createWithoutModel}}
{{-- Example --}} {{#with (state-for model '<STATE_NAME>' bucketName='<BUCKET_NAME>') as |state|}} {{#if state.isEditing}} Editing... {{/if}}{{/with}}
stateFor
Computed Macro
The This addon provides a simple computed property macro which is a proxy to
stateManager.stateFor
.
Note: This macro requires container/owner access.
;;
Advanced Usage
Initial State
In your state file, you can use the initialState
to setup your state object with
initial values.
// app/states/foo.js; const State = EmberObject; State; ;
State Bucketing
State bucketing can be super handy if you want to create multiple states for the same model / stateName combo. Lets say we create a default buffered object state:
// app/states/buffered-object.js; const State = BufferedObjectProxy; State; ;
We can create multiple long lived buffers for the same model.
const bufferA = stateManager;const bufferB = stateManager;
We can make changes to either buffers, display them to the user, and let them select which one they like. Once selected, we can apply the changes and save the model.
Validations & Buffers
We can easily create a validation backed buffered object so we can validate changes before we apply them.
// app/states/validated-buffered-object.js;; const Validations = ;const State = BufferedObjectProxy; State; ;
const buffer = stateManager;await buffer; if buffer buffer; buffer;