若多個 DOM Element 的處理邏輯相同,只有 Data 不同,可共用相同的 Observable 並傳入不同 Template Data 即可。
Version
macOS Catalina 10.15.4
WebStorm 2020.1
Vue 2.6.11
RxJS 6.5.5
Browser
三個 button 各顯示不同 title,但底層都呼叫相同 API,只是傳入 id
不一樣而已。
Data
{
"id": 2,
"title": "RxJS in Action",
"price": 200,
"categoryId": 2,
"image": "rxjs.jpg"
}
http://localhost:3000/books/2
回傳為以上 object。
Template Data
<template>
<div>
<button v-stream:click="{ subject: click$, data: 1 }">Show book 1</button>
<button v-stream:click="{ subject: click$, data: 2 }">Show book 2</button>
<button v-stream:click="{ subject: click$, data: 3 }">Show book 3</button>
<h1>{{ title$ }}</h1>
</div>
</template>
<script>
import { ajax } from 'rxjs/ajax'
import { exhaustMap, pluck } from 'rxjs/operators'
let fetchTitle$ = x => ajax(`http://localhost:3000/books/${x}`).pipe(
pluck('response', 'title')
)
let subscriptions = function() {
let title$ = this.click$.pipe(
pluck('data'),
exhaustMap(fetchTitle$)
)
return { title$ }
}
export default {
name: 'app',
domStreams: ['click$'],
subscriptions,
}
</script>
第 3 行
<button v-stream:click="{ subject: click$, data: 1 }">Show book 1</button>
<button v-stream:click="{ subject: click$, data: 2 }">Show book 2</button>
<button v-stream:click="{ subject: click$, data: 3 }">Show book 3</button>
v-stream
除了可指定要綁定的 DOM event 與 Subject,還可指定要傳入 data,如此可多個 DOM element 同時使用相同 Observable。
14 行
let fetchTitle$ = x => ajax(`http://localhost:3000/books/${x}`).pipe(
pluck('response', 'title')
)
fetchTitle()
呼叫 API 並回傳 title
。
19 行
let title$ = this.click$.pipe(
pluck('data'),
exhaustMap(fetchTitle$)
)
只需一個 title$
Observable 即可,使用 pluck()
動態取出 data
property 的值。
pluck()
從 Observable 中的每個 object 的指定 property 取出值
Observable 的每個 source value 對應一個 property。
Conclusion
- 若使用 event 處理 asynchronous,可共用相同 event handler 並傳入不同 argument;在 FRP 也可共用相同 Observable,只要傳入不同 template data 即可