Todos Redux Multiple Stores
Testing Multiple Mutually Exclusive Stores
by vikikamath
HTML
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/3.6.0/redux.min.js"></script>
<main></main>
<script id="filter" type="text/ractive">
<ul>
{{#filters}}
<li class="{{#if active === .}}active{{/if}}" on-click="setVisible:{{.}}">{{.}}</li>
{{/}}
</ul>
</script>
<script id="todos" type="text/ractive">
<div>
<input type="text" value="{{val}}" placeholder="Enter some text"/>
</div>
<button on-click="add">Add</button>
<ul id="todos">
{{#todos:i}}
<li on-click="toggle:{{i}}" class="{{#if completed}}completed{{/if}}">{{text}}</li>
{{/todos}}
</ul>
</script>
<script id="app" type="text/ractive">
<TodoList todos="{{todoStore.getState()}}"/>
<FilterList active="{{visibilityStore.getState()}}"/>
</script>
CSS
ul {
list-style: none;
}
ul li {
display: inline;
margin: 1rem;
}
ul li.active {
text-decoration: underline;
}
#todos li {
display: block;
}
#todos li.completed {
text-decoration: line-through;
}
JavaScript
// define actions
const setVisibility = (filter) => {
return {
type: 'SELECT_FILTER'
,filter
}
}
const addTodo = (text) => {
return {
type: 'ADD_TODO'
,text
}
}
const toggleTodo = (index) => {
return {
type: 'TOGGLE_TODO'
,index
}
}
// define reducers
const visibility = (state={}, action) => {
switch (action.type) {
case 'SELECT_FILTER':
//console.log('prev state', state)
return action.filter
default:
return state;
}
}
const todos = (state =[], action) => {
switch (action.type) {
case 'ADD_TODO':
console.log(state)
return [
...state
,{
text: action.text
,completed: false
}
]
case 'TOGGLE_TODO':
return state.map((todo, index)=>{
if (index === action.index) todo.completed = !todo.completed
return todo;
})
default:
return state
}
}
// define components
const TodoList = Ractive.extend({
template: `#todos`
,oninit() {
var self = this;
self.on('add', (e) => {
todoStore.dispatch(addTodo(e.context.val));
})
self.on('toggle', (e) => {
console.log(e.index.i);
todoStore.dispatch(toggleTodo(e.index.i))
})
}
,data() {
return {
val: undefined
}
}
})
const FilterList = Ractive.extend({
template: `#filter`
,data() {
return {
filters: [
'ALL'
,'COMPLETE'
,'PENDING'
]
}
}
,oninit() {
var self = this;
self.on('setVisible', (e) =>{
visibilityStore.dispatch(setVisibility(e.context))
})
}
})
// describe initial state
const initialTodo = []
const initialVisibility = 'ALL'
// define the stores
const todoStore = Redux.createStore(todos,initialTodo)
const visibilityStore = Redux.createStore(visibility ,initialVisibility)
// subscribe to store changes
todoStore.subscribe(() => app.update())
visibilityStore.subscribe(() => app.update())
const app = new Ractive({
el: 'main'
...