Created
November 5, 2018 22:12
-
-
Save JBreit/93ecf5e9dea985874d67ab954b3101b2 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export const ADD_TODO = '[Todo] Add Todo'; | |
export const REMOVE_TODO = '[Todo] Remove Todo'; | |
export class AddTodo { | |
readonly type = ADD_TODO; | |
constructor(private payload: any) {} | |
} | |
export class RemoveTodo { | |
readonly type = REMOVE_TODO; | |
constructor(private payload: any) {} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as fromStore from './store'; | |
import { renderTodos } from './utils'; | |
const input = document.querySelector('input') as HTMLInputElement; | |
const button = document.querySelector('button') as HTMLButtonElement; | |
const destroy = document.querySelector('.unsubscribe') as HTMLButtonElement; | |
const todoList = document.querySelector('.todos') as HTMLLIElement; | |
const reducers = { | |
todos: fromStore.reducer, | |
}; | |
const store = new fromStore.Store(reducers); | |
button.addEventListener('click', () => { | |
if (!input.value.trim()) return; | |
const todo = { label: input.value, complete: false }; | |
store.dispatch(new fromStore.AddTodo(todo)); | |
input.value = ''; | |
}, false); | |
const unsubscribe = store.subscribe((state: any) => { | |
renderTodos(state.todos.data); | |
}); | |
destroy.addEventListener('click', unsubscribe, false); | |
todoList.addEventListener('click', function (event) { | |
const target = event.target as HTMLButtonElement; | |
if (target.nodeName.toLowerCase() === 'button') { | |
const todo = JSON.parse(target.getAttribute('data-todo') as any); | |
store.dispatch(new fromStore.RemoveTodo(todo)); | |
} | |
}); | |
store.subscribe((state: any) => console.log('STATE:::', state)); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<base href="/"> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<title>TypeScript Greeter</title> | |
</head> | |
<body> | |
<div id="app-root" role="app"> | |
<p>You have <span></span> todos.</p> | |
<input type="text"> | |
<button type="button" class="addTodo">Add todo</button> | |
<ul class="todos"></ul> | |
<button type="button" class="unsubscribe">Unsubscribe</button> | |
</div> | |
<script src="app.js"></script> | |
</body> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as fromActions from './actions'; | |
export const initialState = { | |
loaded: false, | |
loading: false, | |
data: [{ label: 'Test Todo Application', complete: false }], | |
}; | |
export function reducer(state = initialState, action: { type: string, payload: any }) { | |
switch (action.type) { | |
case fromActions.ADD_TODO: { | |
const todo = action.payload; | |
const data = [...state.data, todo]; | |
return { | |
...state, | |
data, | |
}; | |
} | |
case fromActions.REMOVE_TODO: { | |
const data = state.data.filter(todo => todo.label !== action.payload.label); | |
return { | |
...state, | |
data, | |
}; | |
} | |
} | |
return state; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class Store { | |
private subscribers: Function[]; | |
private reducers: { [key: string]: Function }; | |
private state: { [key: string]: any }; | |
constructor(reducers = {}, initialState = {}) { | |
this.subscribers = []; | |
this.reducers = reducers; | |
this.state = this.reduce(initialState, {}); | |
} | |
get value() { | |
return this.state; | |
} | |
subscribe(fn: any) { | |
this.subscribers = [...this.subscribers, fn]; | |
this.notify(); | |
return () => { | |
this.subscribers = this.subscribers.filter(sub => sub !== fn); | |
}; | |
} | |
dispatch(action: any) { | |
console.log(action); | |
this.state = this.reduce(this.state, action); | |
this.notify(); | |
console.log(this.state); | |
} | |
private notify() { | |
this.subscribers.forEach(fn => fn(this.value)); | |
} | |
private reduce(state: any, action: any) { | |
const newState: any = {}; | |
for (const prop in this.reducers) { | |
newState[prop] = this.reducers[prop](state[prop], action); | |
} | |
return newState; | |
} | |
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const span = document.querySelector('span') as HTMLSpanElement; | |
const todoList = document.querySelector('.todos') as HTMLLIElement; | |
export function renderTodos(collection: any) { | |
if (span && todoList) { | |
span.innerHTML = collection.length; | |
todoList.innerHTML = ''; | |
for (const item of collection) { | |
todoList.innerHTML = ` | |
<li> | |
${item.label} | |
<button type="button" data-todo='${JSON.stringify(item)}'> | |
Delete | |
</button> | |
</li> | |
`; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment