FlowDown
FlowDown is a Redux style data flow management set of mixins and behaviors for Polymer 1.x/2.x applications.
FlowDown rides on top of Polymer's observer system. It watches all the changes in an app level state and propagate the changes to the state receivers' properties, only allowing the state to flow down from the app's top level.
Examples
Installation
bower install --save KanoComputing/flow-down
Usage
Create a new store
MyAppStore = FlowDown; // These two mixins are now available to use.// Keep a reference to use them with your componentsMyAppStoreStateProvider;MyAppStoreStateReceiver; // The store exposes the `addMutator` method// Mutators will be executed in the order they were addedMyAppStore;
Define a top level/headless element as the StateProvider
.
The method is called mutator because it doesn't act as a reducer, but mutates the data. Although this is against one of the rules of Redux, as it's powered by Polymer's observers, and the data cannot flow back up, the integrity of the state is conserved.
Modify the state using Polymer's set/push/splice/etc.
methods:
Store { super; // You can add mutators in the state provider as well this; }
You can either setup your main app element to be your state provider, or create a headless element for that.
Then for each of your elements depending on the sate:
Store // In your properties, `linkState` will tell the // state receiver to let the data from the link to flow into the property static { return item: type: Object linkState: 'selectedItem' items: type: Array linkState: 'items' } { const index = emodel; // Dispatch your actions like you would using redux this; } { this; }
Common Practice
Changing the local properties will not flow up to the state, make sure you only update the state in the mutator or you will break the 1 to 1 relation between the app state and rendered content.
API
window.FlowDown
createStore(initialState)
Creates and returns a newFlowDownStore
.initialState
is optional and will default to{}
FlownDownStore
addMutator(mutator)
Adds a mutator to the store. Mutators will be executed in the order they were added to the store. A mutator signature must be(action) => {}
. The scope of the mutator will contain a set of methods to mutate the state, which come from Polymer's property effects methods- get
- set
- push
- pop
- splice
- shift
- unshift
dispatch(action)
Dispatches an action to the store
When using these methods, you will need to specify state
as the root variable of the path.
Won't work:
this;
Will work
this;
StateProvider
: The state provider mixinStateReceiver
: The state receiver mixinProviderBehavior
: The state provider behaviorReceiverBehavior
: The state receiver behavior
StateProvider
addMutator(mutator)
same as the store'saddMutator
StateReceiver
getState()
returns the store's statedispatch(action)
Dispatches an action to the store
Any element extending the StateReceiver mixin and declaring a linkState
on their properties will have a dynamic link between the property and the state's data setup.
linkState
expect a path to a value in the state (NOT prefixed by state
)
Utils
types
The type property in actions should be unique, but when creating multiple mutators in different files, using a string can end up in duplicate types. The types util takes an array of string as an input and returns an object with the array's items as keys pointing to a symbol, ensuring its uniqueness:
; const TYPES = ; // Now you can use your types in your mutator and dispatches { } // Use to dispatchstore;
Plugins
ArraySelector
You can use the ArraySelectorPlugin to allow your receivers to have a property holding an item from an array in the state, pointed by an index.
To use it, just give the store to the plugin, then use linkArray
and linkIndex
in your receiver to configure the selected item property:
;; // Creat store with array and indexconst store = FlowDown; // Enable the plugin; // Create receiver element static { return // Link the array items: linkState: 'items' // Link the index index: linkState: 'selectedItemIndex' // Configure the item property item: linkArray: 'items' linkIndex: 'index' }
By updateing the state through mutations, the item property will update accordingly, but will but be stored in the state as it is duplicate data.