Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
RxJS概要とリアクティブ アーキテクチャ
Search
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
AIオーケストレーションを活用した 開発ワークフローの設計と実践
bqnq
0
120
Deploying a Full-Stack Bun-Native Framework on Cloudflare Workers
7nohe
0
120
推論の観測、できていますか? 〜 Google Cloud Gemini Enterprise Agent Platformで 3つの Gemini モデルを実測して踏んだ、評価の罠 〜
shukob
PRO
0
180
例外の正しい扱い方 そのエラー try-catchして大丈夫?
jinwatanabe
3
420
ペアプロの価値はコードを書くことだけじゃない
codmoninc
PRO
0
150
AI時代だからこそ、スケールしないことをやろう
yutashigemura
1
120
AI時代に顧客へ最速で価値を 届けるための試行錯誤 〜「AI × マネジメント」領域におけるmentoのケース〜
posterkeisuke
0
110
リージョンの壁を越える、 ちょっと変わったAWSサービスの話
falken
PRO
1
290
When Does a Local Qwen Start to Break
morshoto
0
190
GuardDuty 検知対応を DevOps Agent で効率化しようとしている話 / GuardDuty Investigations with DevOps Agent
masahirokawahara
1
340
AIで開発は速くなったのに、なぜ現場は楽にならないのか 〜あなたの組織のボトルネックを突き止めるワークショップ〜
jacopen
1
300
「図書館」という名前のままでいいのか -Code4Lib JAPANカンファレンス2026 アンカンファレンス報告- / Code4Lib JAPAN Conference 2026: Unconference Report
ykiyota
0
130
Featured
See All Featured
Understanding Cognitive Biases in Performance Measurement
bluesmoon
32
3k
Evolving SEO for Evolving Search Engines
ryanjones
0
280
How to Get Subject Matter Experts Bought In and Actively Contributing to SEO & PR Initiatives.
livdayseo
0
190
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
38
3k
Efficient Content Optimization with Google Search Console & Apps Script
katarinadahlin
PRO
1
840
Winning Ecommerce Organic Search in an AI Era - #searchnstuff2025
aleyda
1
2.1k
Typedesign – Prime Four
hannesfritz
42
3.2k
Building Flexible Design Systems
yeseniaperezcruz
330
41k
Distributed Sagas: A Protocol for Coordinating Microservices
caitiem20
333
23k
Stop Working from a Prison Cell
hatefulcrawdad
274
21k
Deep Space Network (abreviated)
tonyrice
0
300
Making the Leap to Tech Lead
cromwellryan
135
10k
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ͰτϨϯυΛ͍͔͚Α͏ʂ