Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
RxJS概要とリアクティブ アーキテクチャ
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
dsuket
March 21, 2016
Technology
2.3k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
RxJS概要とリアクティブ アーキテクチャ
ng-japan2016でのRxJSの話
dsuket
March 21, 2016
More Decks by dsuket
See All by dsuket
ぼくのアプリがカイゼンできない
dsuket
1
1.4k
Other Decks in Technology
See All in Technology
気づかぬうちにセキュリティ負債を生むAPIキー運用
sgwrmctk
0
180
AIはどのように 組織のアジリティを変えるのか?
junki
4
1k
GitHub Copilot app最速の発信の裏側
tomokusaba
1
170
自分が詳しくない領域でAIを使う #プロヒス2026
konifar
12
4.2k
2026TECHFRESH畢業分享會 - AI 時代的人生存檔點
line_developers_tw
PRO
0
1.3k
【Snowflake Summit 2026 Recap!!】Snowflake Summit Deep Dive: Security & Governance
civitaspo
1
260
SONiCで構築・運用する生成AI向けパブリッククラウドネットワーク ~実装編~
sonic
0
280
マルチアカウント環境での コーディングエージェントを使った障害調査が大変なので AIエージェントにReadOnly権限を付与してみた / ReadOnly AI Agents for Multi-Account AWS Incident Response
yamaguchitk333
2
110
AIチャット検索改善の3週間
kworkdev
PRO
2
140
Oracle AI Database@Azure:サービス概要のご紹介
oracle4engineer
PRO
6
2k
現地で盛り上がった WWDC26 Keynote
zozotech
PRO
1
260
[チョークトーク資料]AWS DevOps Agent を使いこなす / AWS Dev Ops Agent Chalk Talk AWS Summit Japan 2026
kinunori
2
530
Featured
See All Featured
Lessons Learnt from Crawling 1000+ Websites
charlesmeaden
PRO
1
1.3k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
2
860
The Hidden Cost of Media on the Web [PixelPalooza 2025]
tammyeverts
2
330
A designer walks into a library…
pauljervisheath
211
24k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Leo the Paperboy
mayatellez
7
1.8k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
950
sira's awesome portfolio website redesign presentation
elsirapls
0
280
The Anti-SEO Checklist Checklist. Pubcon Cyber Week
ryanjones
0
170
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
4 Signs Your Business is Dying
shpigford
187
22k
Statistics for Hackers
jakevdp
799
230k
Transcript
RxJS֓ཁͱ ϦΞΫςΟϒ ΞʔΩςΫνϟ ng-japan 2016 OpenWeb Technology Daisuke. Takaoka With
About me ߴԬେհ ελʔτΞοϓCTOɺٕज़ސɺٕज़૬ஊͳͲ ϑϩϯτ͔ΒΠϯϑϥ·Ͱ ࠷ۙόοΫΤϯυͰRxJSͬͯ·͢ Angular2ͬͯͳͷͰ ؒҧͬͯͯ͝צห͍ͩ͘͞ŋŋŋ @dsuket
TechFeed IUUQTUFDIGFFEJP *5ςΫϊϩδʔઐͷΩϡϨʔγϣϯαʔϏε
What’s TechFeed ? ڵຯͷ͋ΔτϐοΫΛબ͢ΔͱɺຖͦͷτϐοΫ ʹؔ࿈͢ΔχϡʔεΛϋΠϥΠτͰ͓ಧ͚͠·͢ɻ
ͪΖΜɺ ʮϦΞΫςΟϒϓϩάϥϛϯάʯ τϐοΫ͋Γ·͢ʂ https://techfeed.io/channels/Reactive%20Programming
techfeed.io Register now!!
RxJS֓ཁ
What RxJS? Reactive Extensions for JavaScript • .NETͷϥΠϒϥϦͱͯ͠ੜ • ࣌ؒ࣠ͷ͋ΔඇಉظετϦʔϜ
• ؔܕϦΞΫςΟϒϓϩάϥϛϯάʢFRPʣ • Angular2Ͱ࠾༻ʂ
Functional Reactive programming The introduction to Reactive Programming you've been
missing ݴ͍͍ͨ͜ͱશ෦͜͜ʹ͋Δ ʲ༁ʳ͋ͳ͕ͨٻΊ͍ͯͨϦΞΫςΟϒϓϩάϥϛϯάೖ
ؔܕϦΞΫςΟϒϓϩάϥϛϯά (FRP) ͱ? ʮStackoverflowͷൣతղʯ Conal Elliott • ࣌ؒΛ͔͚ͯμΠφϛοΫʹมԽ͢ΔɺϑΝʔετΫϥεͷ Ͱ͢ɻͦΕΒΛؔͷ in/out
ʹͯ͠Έ߹ΘͤΔ͜ͱ͕Ͱ͖· ͢ɻ͜ΕΛ Behavior ͱݺͼ·͢ɻ • Behavior ɺ੩తͳಈ࡞࣌ܭͷΑ͏ͳ࣌ؒͱ͍͍͔ͬͨͭ͘ͷ ϓϦϛςΟϒͳͷ͔Βߏஙͨ͠ޙɺॱ൪·ͨฒྻʹଓʹ͠ ·͢ɻnݸͷ Behavior ɺ࿈ଓͨ࣌ؒ͠ͷΑ͏ͳࢄతͳ nݸͷ ؔʹΑͬͯ߹͞Ε·͢ɻ • ͦͷ ࢄతݱΛදͨ͢Ίʹ ༗ݶ·ͨແݶʹग़ݱ͢Δετ ϦʔϜΛ࣋ͭ Event ͕͋Γ·͢ɻEvent ࣌ؒͱͷϖΞͰ͢ɻ ݩMSͷResearcherͰFRPͷ࢝ͱݴΘΕΔConal Elliottͷղઆɻ Α͘ࢀর͞ΕΔ͕ɺ৽ਓ͖Ͱͳ͍
ؔܕϦΞΫςΟϒϓϩάϥϛϯά (FRP) ͱ? ʮReactive Manifestoʯ ϦΞΫςΟϒγεςϜͱ: ଈԠੑɺোੑɺྗੑɺϝοηʔδۦಈΛඋ͑Δ ϓϩδΣΫτϚωʔδϟϏδωεܥͷਓؒʹݟͤΔͷͷΑ͏ͩɻ
ؔܕϦΞΫςΟϒϓϩάϥϛϯά (FRP) ͱ? "Rx = Observables + LINQ + Schedulers”
ɾObservables: σʔλετϦʔϜ ɾLINQ(Language-Integrated Query): ΫΤϦ ɾSchedulers: ฏߦੑ੍ޚ ͱͯॏͨ͘ɺզʑΛࠞཚͤ͞ΔϚΠΫϩιϑτతͳͷͩɻ
ؔܕϦΞΫςΟϒϓϩάϥϛϯά (FRP) ͱ? ඇಉظσʔλετϦʔϜΛ༻͍Δϓϩάϥϛϯά • ετϦʔϜͱ࣌ؒॱʹฒΜͩਐߦதͷΠϕϯτͷྻ • ετϦʔϜͷΠϕϯτΛඇಉظʹॲཧ • ετϦʔϜΛ߹ɺ࡞ɺϑΟϧλ͢Δศརͳؔ܈
• ܰྔͰԿͰετϦʔϜʹͰ͖Δ
ϘλϯΫϦοΫͷΠϕϯτετϦʔϜ ΫϦοΫΠϕϯτ ετϦʔϜͷྃ Τϥʔ ࣌ؒॱʹฒΜͩΠϕϯτྻΛඇಉظʹॲཧ͢Δ ετϦʔϜ ʹ Observable (*1) *1
ʢࢲ͜ΕΛഅ໊ࣛ͛ͨલͩͱײ͡ΔͷͰɺετϦʔϜͱݺͿɻ@andrestaltzʣ
μϒϧ ΫϦοΫ ͷྫ
Push vs Pull ObservableϒϩοΫͤͣʹෳͷΛ ϦΞΫςΟϒʹॲཧͰ͖ΔɻPromise++ What are the Reactive Extensions
for JavaScript (RxJS)? ୯ҰͷΓ ෳͷΓ 1VMMಉظతରܕ 0CKFDU "SSBZ 4FU .BQ 0CKFDU 1VTIඇಉظ3FBDUJWF 1SPNJTF 0CTFSWBCMF
Passive vs Reactive BarFoo͔Βૢ࡞͞Εɺ ঢ়ଶ͕֎෦ʹґଘ͢Δɻ BarFooͷΠϕϯτΛड͚ ࣗͰঢ়ଶΛཧ͢Δɻ ReactiveϓϩάϥϛϯάͰࣗʹΛͭϞδϡʔϧΛͭ͘Γɺ֎෦ ͷঢ়ଶΛมߋ͢Δ͜ͱΑΓϞδϡʔϧࣗͷػೳʹযΛ߹ΘͤΔɻ ؔ৺ͷʹܨ͕Δ
Observables › Cycle.js How Reactive Programming can help reduce code spaghetti Passive/Reactive ϓϩάϥϛϯάͷҧ͍ΛֶͿ
ͳͥReactiveProgramming͕ඞཁ͔ʁ ”” ݱͷΞϓϦɺߴʹΠϯλϥΫςΟϒͳମݧϢʔβʔʹ༩͑ ΔͨΊʹɺଟͷϦΞϧλΠϜΠϕϯτΛѻ͍ͬͯΔɻզʑ͜ ΕΛదʹऔΓѻ͏πʔϧΛ୳͓ͯ͠ΓɺϦΞΫςΟϒϓϩάϥ ϛϯά͕ͦͷ͑ͳͷͩɻ @andrestaltz
ͳͥReactiveProgramming͕ඞཁ͔ʁ ”” ϢʔβʔϦΞϧλΠϜΛظ͍ͯ͠ΔɻੈքpushʹҠಈ͠ ͨɻϢʔβʔզʑ։ൃऀ͕͍ͭ͘ͷΛ͍ͬͯΔɻ Intro to Rx - Why Rx?
Rx ʹ͍͍ͯΔͷɺ͍ͳ͍ͷ RxΛ͏͖ͷ • ϚεϘλϯΫϦοΫͷΑ͏ͳUIΠϕϯτɺΞϓϦέʔγϣϯͷΠϕϯτɺΠϯϑ ϥγεςϜͷΠϕϯτɺωοτϫʔΫΠϕϯτɺCEPͳͲͷඇಉظΠϕϯτॲཧશൠ Rx͕͑Δͷ • λεΫɺඇಉظγεςϜίʔϧͳͲ୯Ұͷඇಉظॲཧ ͔ͳ͍ͷ
• طଘͷಉظॲཧΛஔ͖͑Δ͚ͩͷͷ • ϝοηʔδΩϡʔͳͲɺγʔέϯγϟϧͳτϥϯβΫγϣϯ͕ඞཁͳͷ intro to Rx - When is Rx appropriate?
ECMAScript Observable • Observable ͕ ES7ʹఏҊ͞Ε͍ͯͯೖΓͦ͏ https://github.com/zenparsing/es-observable ೦ͷͨΊɺAngular1Ϣʔβʔʹࢥ͍ೖΕਂ͍ Object.observe ͱผw
ࠓͪΌΜͱೖΓͦ͏ʁ • RxJS(v5) ES7 Observable ४ڌ
Rxͷؒୡ Languages • RxJava, RxJS, Rx.NET, RxScala, RxGroovy, RxJRuby, •
UniRx, RxCpp, RxClojure, Rx.rb RxPY, RxKotlin, RxSwift Platforms and frameworks • RxNetty, RxAndroid, RxCocoa http://reactivex.io/languages.html
Other FRP libraries • Bacon.js • RxJSͷޙൃ FRPϥΠϒϥϦɻRxJSΑΓҰ؏ੑ͋Γɺ ͍͍͕͢ύϑΥʔϚϯεʹগ͋͠Γʁ •
Kefir • Bacon.jsͷ͞ΒʹޙൃɻলαΠζɺলϝϞϦɻ ͲͪΒES7 ObservableͱҟͳΓͦ͏ͳͨΊɺࠓޙ͕ඍົ
RxJSجૅ
RxJSͷҙ • ݱࡏ RxJS 4ܥͱ5ܥ͕͋ΓɺϦϙδτϦ͕ҧ͏ • 4ܥ: Reactive-Extensions/RxJS •
5ܥ: ReactiveX/RxJS ʢ·ͩbeta2ɻAngular2Ͱ࠾༻ʣ • v5ͰAPI͕౷ഇ߹͞Εͯ݁ߏมΘͬͯΔʂ • ᷿ͷυΩϡϝϯτ΄ͱΜͲ͕4ܥɻ֓೦େ͖͘มΘͬͯͳ͍͕ɻɻ • Migrating from RxJS 4 to 5 ඞಡ • ·ͩυΩϡϝϯτ͞Εͳ͍ଟ͍ͷͰιʔεಡΉඞཁ • ຊࢿྉ v5 ରԠͰઆ໌͠·͢
RxJSͷجຊ RxJS = Observables + Operators + Schedulers • Observable:
σʔλετϦʔϜ Rx.Observable.of / from / create ͳͲͰࣗ༝ʹ࡞ΕΔɻ • Operators: ΫΤϦ mapͱ͔filterͱ͔ɺObservableΛૢ࡞͢Δؔ • Schedulers: ฒߦੑͷίϯτϩʔϧ
جຊతͳॲཧ • ݩͷsource͔ΒObservableΛ࡞͠ɺΦϖϨʔλͰૢ ࡞͠ɺͦͷ݁ՌΛड͚ͯॲཧ͢Δɻ • ετϦʔϜ͔ΒσʔλΛड͚औΔ͜ͱΛSubscribeͱ͍ ͏ɻ • v5 Ͱ
ES7 ObservableͷΠϯλʔϑΣΠεʹ߹Θͤͨ • ʢجຊతʹʣSubscribe͢Δͱσʔλ͕ྲྀΕ࢝ΊΔɻ
؆୯ͳαϯϓϧ const stream = Rx.Observable.range(0,5) // 0,1,2,3,4 .map(x => x
* 3) // => 0,3,6,9,12 .filter(x => x%2); // => 3,9 stream.subscribe({ next: x => console.log(‘Next:' + x), error: err => console.error('Error:', err), complete: () => console.log('Completed'), }); => "Next:3" => "Next:9" => "Completed"
API֓ཁ • ͱʹ͔͘ΦϖϨʔλͷ͕ଟ͍ɻ • v4ܥͰ144ݸɺv5.0.0.beta.2Ͱ98ݸ • ੜɺมɺϑΟϧλϦϯάɺ݁߹ͳͲ • Ҏ߱Α͘͏ϐοΫΞοϓ
ࢀߟ: reactivex.io • RxͷΦϖϨʔλΛݴޠຖʹղઆ • ਤ͕ղɻ׳ΕΕಡΊΔ
ࢀߟ: RxMarbles • ΦϖϨʔλΛΠϯλϥΫςΟϒʹਤղ
ࢀߟ: ͦͷଞΑ͘ಡΉࢿྉ • RxJS/observable.md at master · Reactive-Extensions/RxJS • v4ͷAPIυΩϡϝϯτ
• RxJS/MIGRATION.md at master · ReactiveX/RxJS • v4͔Β5ͷϚΠάϨʔγϣϯΨΠυ • RxJS/src/operator at master · ReactiveX/RxJS • v5 ͷΦϖϨʔλҰཡʢsrcʣ • RxJS Advent Calendar 2015 • @bouzuya ͞ΜͷᕒͷಠΓΞυΧϨ
ੜ • Rx.Observable.of • ୯ҰͷΛͱΓɺͦΕΛฦ͢ετϦʔϜΛੜ • just/return ofʹٵऩ͞Εͨ • Rx.Observable.from
• ྻɺPromiseɺObservableͳͲΛऔΓɺͦΕΒෳͷͷετ ϦʔϜΛੜ • Rx.Observable.range / repeat • ࢦఆൣғɺ·ͨͷ࿈ଓͨ͠ετϦʔϜΛੜ • Rx.Observable.interval / timer • ҰఆִؒͰ܁Γฦ͢ • Rx.Observable.create • subscriberΛҾʹҙͷΛྲྀ͢ετϦʔϜΛੜ
ม • map (select) • Λม͢Δ • select v5
ͰഇࢭɻΛऔΔ߹ɺmapTo ʹɻ • mergeMap (flatMap) • map ݁Ռ͕Observableྻͷ߹Α͘͏ • v5 Ͱ mergeMap ʹɻObservableΛऔΔ߹ɺmergeMapTo ʹɻ • scan • reduceͬΆ͍͕ɺΛྲྀ͢ • groupBy • άϧʔϓ͚ʢׂʣ͢Δ • buffer / bufferCount / bufferTime • ࣌ؒͰΠϕϯτ·ͱΊΔ
ϑΟϧλϦϯά • filter (where) • ͳͲͰϑΟϧλϦϯά͢Δ • where v5
Ͱഇࢭɻ • first / last • ࠷ॳ࠷ޙͷ͚ͩΛऔΔ • skip / skipLast • ࢦఆͷnݸΛඈ͢ɻskipLast v5Ͱഇࢭ • take / takeLast • ࢦఆͷnݸΛऔಘ͢ΔɻtakeLast࠷ޙͷnݸɻ • distinct • ϢχʔΫʹͯ͠औಘ͢Δɻ • sample / debounce • ࢦఆִؒຖͷ࠷ޙͷΛऔಘ͢Δɻ
݁߹ • startWith • ॳظΛ࠷ॳʹૠೖ • merge • ετϦʔϜΛ݁߹͢ΔɻෳͰOK •
switch • ετϦʔϜΛॱʹྲྀ͢ • combineLatest • ෳͷετϦʔϜͷ࠷ޙͷΛ݁߹͢Δɻ • Ͳ͔͜1ͭͰདྷΕɺଞͷετϦʔϜͷۙͷͱ݁߹͢Δ • zip • ෳͷετϦʔϜͷ࠷ޙͷΛ݁߹͢Δɻ • શ෦ἧ͔ͬͯΒग़ྗ͞ΕΔɻ • and / then / when • v5Ͱഇࢭʁ
࣮ફRxJS
ζϯυίΩϤγ
·ͩ·ͩଓ͘ŋŋŋ
࡞ͬͯΈͨ https://jsbin.com/kecove/edit?js,console
ղઆ1: randomStream const randomStream = Rx.Observable .create(observer => { observer.next(!Math.floor(Math.random()*2));
observer.complete(); }); Everything is a stream Observable.create ͰɺϥϯμϜʹtrue/falseΛฦ͢ ετϦʔϜΛ࡞
ղઆ2: zundokoStream const zun = Rx.Observable.of('ズン'); const doko = Rx.Observable.of('ドコ');
return randomStream .flatMap(val => (val ? zun : doko)); “ζϯ” ͱ ”υί” Λฦ͢ετϦʔϜΛ࡞͠ɺ randomStreamͷʹΑͬͯΓସ͑Δɻ
ղઆ3: intervalStream return Rx.Observable.interval(400) .mergeMapTo(zundoko) .do(val => console.log(val)) .bufferCount(5, 1)
.takeWhile(val => val.join('') !== 'ズンズンズンズンドコ'); Observable.interval Ͱ 400msຖʹ܁Γฦ͢ετϦʔϜΛ࡞͠ ͦΕΛmargeMapToͰzundokoStreamʹஔ͖͑Δɻ doͰ్த݁ՌΛग़ྗͭͭ͠ɺbufferCount ͰskipΛ1Ͱ5ݸηο τɻtakeWhile ͰతͷจࣈྻʹͳΔ·Ͱ܁Γฦ͢ɻ
ղઆ4: subscribe const source = createStream(); source.subscribe({ next: () =>
{}, error: err => console.log('Error: ', err), complete: () => console.log('キ・ヨ・シ!'), }); ࡞ͨ͠StreamΛsubscribeͯ͠ɺྃ࣌ʹจࣈ ྻΛग़ྗ͢Δɻ
༨ஊ ಉ͜͡ͱ͕͜Ε1ߦ(87byte)ͰࡁΈ·͢ʢྦ ʢ͖ͬ͞ͷ764byteʣ for(n=3;n-64;console.log(n-64?(n|=2*Math.random())&1?' ドコ':'ズン':'キ・ヨ・シ!'))n<<=6 jsͰζϯυίΩϤγͷίʔυΰϧϑ
RxJS·ͱΊ • ࠓ͔ΒReactive ProgrammingΔͳΒRxJS 5ʂ • ΦϖϨʔλ͕ࢁ΄Ͳ͍͋ͬͯ͜ͳ͢ͷ ͍͠ɻ • ·͍ͣ͜͠ͱߟ͑ͣʹɺجຊతͳΦϖϨʔ
λͰ࡞ͬͯΈΔɻ ʢͦ͏͠ͳ͍ͱ͍ͭ·Ͱ͠ͳ͍ɾɾɾʣ
Reactive Architecture RxJS + 2
RxJS in Angular2 • Angular2ͰҰ෦ͰRxJSΛ࠾༻ • HTTP • EventEmitter •
ίϯϙʔωϯτΠϕϯτHTTPϦΫΤετΛ Observableͱͯ͠ѻ͑Δʂ • ViewͰObservableΛදࣔՄೳ
Angular2 Architecture Angular2Componentࢦ RxJSͬͯσʔλϑϩʔΛߟ͑ΒΕͳ͍͔
Reactive Architecture UNIDIRECTIONAL USER INTERFACE ARCHITECTURES ϢʔβʔΠϕϯτΛ୯Ұํͷσʔλϑϩʔͱ ͯ͠ѻ͏ΞʔΩςΫνϟͷҰཡΛհ FluxɺReduxɺBESTɺModel-View-Updateɺ Model-View-IntentɺNested
Dialogues
Flux • Store, View, Action, Dispatcher ͔ΒΔ • ViewReactComponentͷೖΕࢠʹͳΔ •
ViewͰϨϯμϦϯάͱΠϕϯτϋϯυϦϯάΛߦ͏
Redux • Singleton Store, Provider, Actions, Reducers • View ProviderReactҎ֎ʹAngularɺEmberͳͲͰՄ
• View͔ΒAction͕ݺΕɺActionຖʹReducerͰstateΛߋ৽͢Δ
Model-View-Update • “The Elm Architecture” ͱͯ͠ΒΕΔɻRedux͜Εʹinspire͞Εͨɻ • Model, View, Action,
UpdateΛComponentͱͯ͠֊ߏԽͰ͖Δɻ
Model-View-Intent • Cycle.js Ͱ࠾༻͞Ε ObservableΠϕϯτετϦʔϜΛσʔλϑϩʔͱ͢Δ • UserΠϕϯτϋϯυϥIntentͰએݴ͞ΕɺϨϯμϦϯάͱ • MVIComponentʹͳΓɺ֊తʹ͑Δ
Angular2ͰͷReactive Architectureͷݕ౼ • Angular2ͷComponentར༻͍ͨ͠ɻ֊Խͱؚ͔Ίɻ • MVIͷObservableத৺ͷߟ͑Αͦ͞͏ɻ • ComponentʹModelɼIntent૬ΛObservableͰೖΕͯΈΔɻ • ϞσϧΛObservableʹ͠ɺViewͰͦΕΛ͏
• ΠϕϯτϋϯυϦϯάAngularͷόΠϯσΟϯά͕ศརͳͷͰͦΕ Λ͏ɻ • όΠϯσΟϯάΛView͔Βग़͢͜ͱ͕ඞͣ͠ਖ਼ղͰͳ͍ͷͰɻʢؔ৺ͱٕज़ͷ ʣ
$PNQPOFOU Angular2 MVI 6TFS .PVTF *OUFOU 0CTFSWBCMF .PEFM Πϯελϯεม
0CTFSWBCMF 7JFX UFNQMBUF 4DSFFO formCtrl͔ΒϢʔβʔҙਤ ΛΠϯςϯτͱͯ͠Observableʹ Πϯςϯτ͔ΒΛऔΓग़͢ ObservableͳΠϯελϯεม ObservableมΛ asyncͰviewʹόΠϯυ
Angular2 MVI Sample ຯͳαϯϓϧ࡞ͬͯΈͨɻ • https://github.com/dsuket/angular2-mvi
@Component({ selector: 'bmi', styles: [require('./bmi.component.scss')], template:` <div class="bmi-calc"> <div class="weight">
<div class="label">Weight: </div> <input id="#weight" type=“range" [ngFormControl]="weightCtrl"> {{weight$ | async}} kg </div> <div class="height"> <div class="label">Height: </div> <input id="#height" type=“range" [ngFormControl]="heightCtrl"> {{height$ | async}} cm </div> <h3>BMI is {{bmi$ | async}}</h3> </div> `, directives: [FORM_DIRECTIVES], }) bmi.component.ts
export class BmiComponent { // Models private weight$; private height$;
private bmi$; // Controls private weightCtrl = new Control(); private heightCtrl = new Control(); constructor() { // Intents const weightChanges = this.weightCtrl.valueChanges; const heightChanges = this.heightCtrl.valueChanges; // Bind intents to models this.weight$ = weightChanges.map(Number).startWith(60); this.height$ = heightChanges.map(Number).startWith(170); this.bmi$ = this.weight$.combineLatest(this.height$) .map(this.calcBmi); } calcBmi(data) { const [weight, height] = data; const heightMeters = height * 0.01; return Math.round(weight / (heightMeters * heightMeters)); } } bmi.component.ts
ߟ Pros • ͳ͔ͳ͔ΩϨΠʹॻ͚ͦ͏ɻ • @Input ͳͲͰObservableΛΓͱΓͯ͠ɺComponentؒ࿈ܞ؆୯ ʹͰ͖ͦ͏ɻ Cons •
ຖճ async ॻ͘ͷ͕ͪΐͬͱ໘͍͘͞ɻ • ͦͦ͜ͷॻ͖ํ͕ͤͳͷ͔Ͳ͏͔Α͔͘Βͳ͍ɻɻ • ύϑΥʔϚϯεతʹͲ͏͔ؾʹͳΔɻ • ngFor ͕ Observable Λͦͷ··ѻ͑ͳ͍ͷ͕೦
༨ஊ ͖ͬ͞ͷ zundoko Λ Angular2 + MVI Ͱ࡞ͬͨ • dsuket/zundoko-angular
• Demo લηογϣϯͰ @shumpei ͕࡞ͬͨελʔλʔΩοτ͙͑͢Ͱ͖ͨɻ ͚Ͳɺશ෦ObservableͰ࡞ΔͷπϥΠŋŋŋ ࣌ؒͷ߹Ͱ݁ہී௨ͷόΠϯσΟϯάʹͳͬͨͱ͜Ζ
ࢀߟ • Cycle.js • Reactive Data Flow in Angular 2
• How to build Angular 2 apps using Observable Data Services - Pitfalls to avoid • Taking advantage of Observables in Angular 2 • todomvc-ng2-reactive • angular2-reactive-starter
·ͱΊ • ObservableES7Ͱ࠾༻͞Εͦ͏ͳͷͰɺࠓ ͔Β͓ͬͯ͜͏ʂ • ObservableΛத৺ͱͨ͠σʔλϑϩʔΞʔΩς ΫνϟࠓྲྀߦΔʂʁ • TechFeedͰτϨϯυΛ͍͔͚Α͏ʂ