Skip to content

Instantly share code, notes, and snippets.

@jackhftang
Created September 29, 2017 17:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jackhftang/df362ddf6b8dd7eb1d27cac2f8c68aa6 to your computer and use it in GitHub Desktop.
Save jackhftang/df362ddf6b8dd7eb1d27cac2f8c68aa6 to your computer and use it in GitHub Desktop.
A taste of rxjs + d3
<div>
<ul class="list"></ul>
Item: <input type="text" class="input_todo"/>
<button class="btn_push">Push</button>
<button class="btn_pop">Pop Last</button>
<br>
<span class="msg"></span>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.4.3/Rx.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.10.2/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script type="text/javascript">
///////////////////////////////////////////////////////////
// helper
const parentNode = function () {
return this.parentNode
}
///////////////////////////////////////////////////////////
// intent
const push$ = new Rx.Subject();
const pop$ = new Rx.Subject();
const check$ = new Rx.Subject();
///////////////////////////////////////////////////////////
// model
const initList = [
{checked: false, text: "foo"}
];
const lastItem$ = new Rx.BehaviorSubject();
const list$ = Rx.Observable.merge(
push$.map(x => [1, x]),
pop$.map(x => [2, x]),
check$.map(x => [3, x])
).scan((acc, [type, x]) => {
if (type === 1) acc.push(x);
else if (type === 2 && acc.length) lastItem$.next(acc.pop());
else if (type === 3) acc[x].checked = !acc[x].checked;
return acc
}, initList).startWith(initList);
///////////////////////////////////////////////////////////
// wiring
$('.btn_push').click(e => {
push$.next({
checked: false,
text: $('.input_todo').val()
})
});
$('.btn_pop').click(e => {
pop$.next(e)
});
lastItem$.subscribe(function (item) {
if (item) {
$('.msg').text(`Last popped: ${item.text}, Is completed? ${item.checked ? 'yes' : 'no'}`)
}
});
list$.subscribe(function (list) {
let x = d3.select('ul.list').selectAll('li').data(list);
x.enter()
.append('li')
.append('input').attr('type', 'checkbox').property('checked', x => x.checked)
.on('click', function (e, i) {
check$.next(i);
})
.select(parentNode)
.append('span')
.text(x => x.text);
x.exit().remove();
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment