Slide 1

Slide 1 text

$ZDMFKT ϦΞΫςΟϒɾϓϩάϥϛϯάʹಛԽͨ͠+4ϑϨʔϜϫʔΫ - A functional and reactive JavaScript framework for predictable code - /BPLJ:"."%" !XBLBNTIB /PEFֶԂ࣌ݶ໨.FHVSPFTº(PUBOEBKT

Slide 2

Slide 2 text

8IBU`T$ZDMFKT $ZDMFKTͬͯԿʁ

Slide 3

Slide 3 text

7JSUVBM%0. 0CTFSWBCMF 0CTFSWBCMFͱ7JSUVBM%0.Λ XFCΞϓϦ։ൃ͠΍͘͢͢ΔͨΊʹʰബ͘ʱϥοϓͨ͠΋ͷ 8IBU`T$ZDMFKT

Slide 4

Slide 4 text

-JCSBSJFTUIBUTVQQPSU$ZDMFKT

Slide 5

Slide 5 text

YTUSFBN3Y+4 w 0CTFSWBCMFTͱ͍͏ΞʔΩςΫνϟΛ༻͍ͨϦΞΫςΟϒϓ ϩάϥϛϯά༻ͷϥΠϒϥϦ w ඇಉظॲཧΛ؆͔ܿͭՄಡੑߴ͘ίʔσΟϯάͰ͖Δ w YTUSFBN͸3T+4ͷܰྔ൛ w ˞ΦϖϨʔλͷ਺΍ϝιου໊͕Ұ෦ҟͳΔ w 3Y+4Ͱͷ୅༻΋Մೳ w ˞Ұ෦Ωϟετ͕ඞཁ

Slide 6

Slide 6 text

4OBCCEPN w Ծ૝%0.ΛૢΔγϯϓϧͳϥΠϒϥϦ w ϞδϡʔϧػೳΛ༗͓ͯ͠Γɺػೳ֦ு͕༰қʹՄೳ w %0.ੜ੒෦෼͸)ZQFS4DSJQUͷΞʔΩςΫνϟΛ࠾༻ w div()΍input()ͳͲ)5.-λά໊ͦͷ··ͷϝιο υ໊͕༻ҙ͞Ε͍ͯΔ

Slide 7

Slide 7 text

#BTJD&YBNQMF ಈ͔ͯ͠ΈΑ͏

Slide 8

Slide 8 text

#BTJD&YBNQMF

Slide 9

Slide 9 text

import {Observable} from 'rxjs'; import {div, label, input, hr, h1, VNode, makeDOMDriver} from '@cycle/dom'; import {run} from '@cycle/rxjs-run'; import {DOMSource} from '@cycle/dom/rxjs-typings'; type Sources = { DOM: DOMSource; } type Sinks = { DOM: Observable; } /** * ΞϓϦέʔγϣϯ * @param sources * @returns {{DOM: Observable}} */ function main(sources: Sources): Sinks { // ΩʔೖྗΠϕϯτΛऔಘ ( Intent ) const input$: Observable = sources.DOM.select('.field').events('input'); // ೖྗΠϕϯτ͔Βݱࡏͷঢ়ଶͳ͍͠஋Λऔಘ ( Model ) const name$: Observable = Observable.from(input$) .map((ev: Event) => ev.target.value) .startWith(''); // ݱࡏͷঢ়ଶΛը໘ʹඳը ( View ) const vdom$: Observable = name$.map(name => {

Slide 10

Slide 10 text

/** * ΞϓϦέʔγϣϯ * @param sources * @returns {{DOM: Observable}} */ function main(sources: Sources): Sinks { // ΩʔೖྗΠϕϯτΛऔಘ ( Intent ) const input$: Observable = sources.DOM.select('.field').events('input'); // ೖྗΠϕϯτ͔Βݱࡏͷঢ়ଶͳ͍͠஋Λऔಘ ( Model ) const name$: Observable = Observable.from(input$) .map((ev: Event) => ev.target.value) .startWith(''); // ݱࡏͷঢ়ଶΛը໘ʹඳը ( View ) const vdom$: Observable = name$.map(name => { return div('.well', [ div('.form-group', [ label('Name: '), input('.field.form-control', {attrs: {type: 'text'}}), ]), hr(), h1(`Hello ${name}`) ]); }); // ݁ՌΛυϥΠόʹग़ྗ͢Δ ( Sinks ) return { DOM: vdom$ }; }

Slide 11

Slide 11 text

label('Name: '), input('.field.form-control', {attrs: {type: 'text'}}), ]), hr(), h1(`Hello ${name}`) ]); }); // ݁ՌΛυϥΠόʹग़ྗ͢Δ ( Sinks ) return { DOM: vdom$ }; } // ΞϓϦέʔγϣϯ͔Βͷ໭Γ஋Λड͚औΔυϥΠό܈Λఆٛ const drivers = { DOM: makeDOMDriver('#app-container') }; // ΞϓϦέʔγϣϯͱυϥΠόΛ݁ͼ͚ͭΔ run(main, drivers);

Slide 12

Slide 12 text

label('Name: '), input('.field.form-control', {attrs: {type: 'text'}}), ]), hr(), h1(`Hello ${name}`) ]); }); // ݁ՌΛυϥΠόʹग़ྗ͢Δ ( Sinks ) return { DOM: vdom$ }; } // ΞϓϦέʔγϣϯ͔Βͷ໭Γ஋Λड͚औΔυϥΠό܈Λఆٛ const drivers = { DOM: makeDOMDriver('#app-container') }; // ΞϓϦέʔγϣϯͱυϥΠόΛ݁ͼ͚ͭΔ run(main, drivers);

Slide 13

Slide 13 text

%FTJHOQIJMPTPQIZPG$ZDMFKT $ZDMFKTͷઃܭࢥ૝

Slide 14

Slide 14 text

Application Application %FTJHOQIJMPTPQIZPG$ZDMFKT

Slide 15

Slide 15 text

driver() main() %FTJHOQIJMPTPQIZPG$ZDMFKT

Slide 16

Slide 16 text

driver() main() ෭࡞༻ ( Effective ) DOM API %FTJHOQIJMPTPQIZPG$ZDMFKT

Slide 17

Slide 17 text

driver() main() ෭࡞༻ ( Effective ) DOM API Source Stream %FTJHOQIJMPTPQIZPG$ZDMFKT

Slide 18

Slide 18 text

driver() main() ঢ়ଶ ( State ) ෭࡞༻ ( Effective ) DOM API Source Stream %FTJHOQIJMPTPQIZPG$ZDMFKT

Slide 19

Slide 19 text

driver() main() ঢ়ଶ ( State ) ෭࡞༻ ( Effective ) DOM API Source Stream Sink Stream %FTJHOQIJMPTPQIZPG$ZDMFKT

Slide 20

Slide 20 text

Rx.Observable .timer(0, 1000) .map(i => `Seconds elapsed: ${i}`) .subscribe( (text: string) => { const container = document.querySelector('#app'); container.textContent = text; } ); ঢ়ଶ ( State ) ෭࡞༻ ( Effective ) %FTJHOQIJMPTPQIZPG$ZDMFKT

Slide 21

Slide 21 text

Rx.Observable .timer(0, 1000) .map(i => `Seconds elapsed: ${i}`) .subscribe( (text: string) => { const container = document.querySelector('#app'); container.textContent = text; } ); ঢ়ଶ ( State ) ෭࡞༻ ( Effective ) %FTJHOQIJMPTPQIZPG$ZDMFKT

Slide 22

Slide 22 text

Rx.Observable .timer(0, 1000) .map(i => `Seconds elapsed: ${i}`) .subscribe( (text: string) => { const container = document.querySelector('#app'); container.textContent = text; } ); Observable Subject ঢ়ଶ ( State ) ෭࡞༻ ( Effective ) %FTJHOQIJMPTPQIZPG$ZDMFKT

Slide 23

Slide 23 text

function main() { return Rx.Observable .timer(0, 1000) .map(i => `Seconds elapsed: ${i}`); } function DOMDriver(text$: Observable) { text$.subscribe( (text: string) => { const container = document.querySelector('#app'); container.textContent = text; } ); } Observable Subject %FTJHOQIJMPTPQIZPG$ZDMFKT

Slide 24

Slide 24 text

function main() { return Rx.Observable .timer(0, 1000) .map(i => `Seconds elapsed: ${i}`); } function DOMDriver(text$: Observable) { text$.subscribe( (text: string) => { const container = document.querySelector('#app'); container.textContent = text; } ); } // Run const sink = main(); DOMDriver(sink);

Slide 25

Slide 25 text

function main() { return Rx.Observable .timer(0, 1000) .map(i => `Seconds elapsed: ${i}`); } function DOMDriver(text$: Observable) { text$.subscribe( (text: string) => { const container = document.querySelector('#app'); container.textContent = text; } ); } // Run const sink = main(); DOMDriver(sink); // υϥΠό܈Λఆٛ
 const drivers = {
 DOM: makeDOMDriver('#app')
 };
 // main ͱυϥΠόΛ݁ͼ͚ͭΔ
 run(main, drivers);

Slide 26

Slide 26 text

*OUSPEVDFNZTFMG Զͷ໊લΛݴͬͯΈΖ ࣗݾ঺հ

Slide 27

Slide 27 text

גࣜձࣾϦΫϧʔτϚʔέςΟϯάύʔτφʔζ XFCϑϩϯτΤϯυΤϯδχΞ ࢁా ௚थ /BPLJ:"."%" *OUSPEVDFNZTFMG !XBLBNTIB

Slide 28

Slide 28 text

http://tech.recruit-mp.co.jp NET BIZ DIV. TECH BLOG

Slide 29

Slide 29 text

No content

Slide 30

Slide 30 text

http://tech.recruit-mp.co.jp 3.1 ϒϩά

Slide 31

Slide 31 text

5IBOLZPV