-
-
Save 3den/4a9e605ac645b90a499dc330421708ff to your computer and use it in GitHub Desktop.
basic Rx "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
// **** Framework ******* | |
function createAction(reducer) { | |
const subject$ = new Rx.Subject(); | |
return { | |
dispatch (payload) { | |
subject$.onNext(payload); | |
}, | |
stream$: subject$.map((payload) => { | |
return reducer.bind(reducer, payload); | |
}) | |
}; | |
} | |
function createState$(initState, actions=[]) { | |
const action$ = actions.reduce((stream$, action) => { | |
return stream$.merge(action.stream$); | |
}, Rx.Observable); | |
return action$ | |
.startWith(initState) | |
.scan(function (state, reducer) { | |
return reducer(state); | |
}); | |
} | |
// **** App ************************* | |
// What is the best way to do this with Rx???? | |
function incrementWithAjaxCall(data) { | |
// do something fancy, request weird stuff on ajax | |
// than you can dispatch the action | |
// this can be an ajax call or anything async | |
const ajax$ = Rx.Observable.from([data.i]); | |
ajax$.subscribe(incrementAction.dispatch); | |
} | |
const incrementAction = createAction(function(payload=1, state) { | |
return Object.assign({}, state, { | |
count: state.count + payload | |
}); | |
}); | |
const decrementAction = createAction(function(payload=1, state) { | |
return Object.assign({}, state, { | |
count: state.count - payload | |
}); | |
}); | |
const initState = {count: 0}; | |
const state$ = createState$(initState, [ | |
incrementAction, | |
decrementAction | |
]); | |
const bigCount$ = state$ | |
.map((state) => state.count ) | |
.filter((count) => count > 10); | |
// side effects, could render component instead | |
const counter = document.getElementById("counter"); | |
// I can filter the state more and subscribe to it | |
bigCount$.subscribe((count) => { | |
counter.style.fontSize = count * 2 + 'px'; | |
}); | |
// I can subscribe to the naked state | |
state$.subscribe((state) => { | |
counter.innerHTML = state.count; | |
}); |
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> | |
<head> | |
<meta charset="utf-8"> | |
<meta name="viewport" content="width=device-width"> | |
<title>JS Bin</title> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.1.0/rx.all.compat.js"></script> | |
</head> | |
<body> | |
<h2>Counter: <span id="counter"></span></h2> | |
<button onclick="incrementWithAjaxCall({i: 10})">Increment</button> | |
<button onclick="decrementAction.dispatch()">Decrement</button> | |
</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
// This code does the same a mini-framework.js but is more verbose | |
function projectIncrement() { | |
return function (state) { | |
return Object.assign({}, state, { | |
count: state.count + 1 | |
}); | |
}; | |
} | |
function projectDecrement() { | |
return function (state) { | |
return Object.assign({}, state, { | |
count: state.count - 1 | |
}); | |
}; | |
} | |
var initState = { count: 0 }; | |
var increment$ = new Rx.Subject(); | |
var decrement$ = new Rx.Subject(); | |
var state$ = Rx.Observable | |
.merge( | |
increment$.map(projectIncrement), | |
decrement$.map(projectDecrement) | |
) | |
.startWith(initState) | |
.scan(function (state, project) { | |
console.log('inc1', state, project); | |
return project(state); | |
}); | |
state$.subscribe(function (state) { | |
var counter = document.getElementById("counter"); | |
counter.innerHTML = state.count; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment