|
130 | 130 | :namespaced/id ;; <-- namespaced keywords are often used |
131 | 131 | [one two three] ;; <-- a seq of interceptors |
132 | 132 | (fn [{:keys [db] :as cofx} [_ arg1 arg2]] ;; destructure both arguments |
133 | | - {:db (assoc db :some-key arg1) ;; return a map of effects |
| 133 | + {:db (assoc db :some-key arg1) ;; return a map of effects |
134 | 134 | :fx [[:dispatch [:some-event arg2]]]})) |
135 | 135 | " |
136 | 136 | {:api-docs/heading "Event Handlers"} |
|
197 | 197 |
|
198 | 198 | The three arguments are: |
199 | 199 |
|
200 | | - - `query-id` - typically a namespaced keyword (later used in subscribe) |
201 | | - - optionally, an `input signals` function which returns the input data |
202 | | - flows required by this kind of node. |
203 | | - - a `computation function` which computes the value (output) of the |
204 | | - node (from the input data flows) |
| 200 | + - `query-id` - typically a namespaced keyword (later used in subscribe) |
| 201 | + - optionally, an `input signals` function which returns the input data |
| 202 | + flows required by this kind of node. |
| 203 | + - a `computation function` which computes the value (output) of the |
| 204 | + node (from the input data flows) |
205 | 205 |
|
206 | 206 | Later, during app execution, a call to `(subscribe [:sub-id 3 :blue])`, |
207 | 207 | will trigger the need for a new `:sub-id` Signal Graph node (matching the |
|
214 | 214 | use of `subscribe` in a `View Function`. |
215 | 215 |
|
216 | 216 | `reg-sub` arguments are: |
| 217 | +
|
217 | 218 | - a `query-id` (typically a namespaced keyword) |
218 | 219 | - a function which returns the inputs required by this kind of node (can be supplied in one of three ways) |
219 | 220 | - a function which computes the value of this kind of node (can be supplied in one of three ways) |
220 | 221 |
|
221 | 222 | The `computation function` is always the last argument supplied and has three ways to be called. |
222 | 223 | Two of these methods are syntactic sugar to provide easier access to functional abstractions around your data. |
223 | 224 |
|
224 | | - 1. A function that will accept two parameters, the `input-values` and `query-vector`. This is the |
| 225 | + 1. A function that will accept two parameters, the `input-values` and `query-vector`. This is the |
225 | 226 | standard way to provide a `computation-function` |
226 | | - #!clj |
227 | | - (reg-sub |
228 | | - :query-id |
229 | | - (fn [input-values query-vector] |
230 | | - (:foo input-values))) |
| 227 | +
|
| 228 | + #!clj |
| 229 | + (reg-sub |
| 230 | + :query-id |
| 231 | + (fn [input-values query-vector] |
| 232 | + (:foo input-values))) |
231 | 233 |
|
232 | 234 | 2. A single sugary tuple of `:->` and a 1-arity `computation-function`: |
233 | | - #!clj |
234 | | - (reg-sub |
235 | | - :query-id |
236 | | - :-> computation-fn) |
237 | 235 |
|
238 | | - This sugary variation allows you to pass a function that will expect only one parameter, |
239 | | - namely the `input-values` and entirely omit the `query-vector`. A typical `computation-function` |
240 | | - expects two pramenters which can cause unfortunate results when attempting to use |
241 | | - clojure standard library functions, or other functions, in a functional manner. |
| 236 | + #!clj |
| 237 | + (reg-sub |
| 238 | + :query-id |
| 239 | + :-> computation-fn) |
242 | 240 |
|
243 | | - For example, a significant number of subscriptions exist only to get a value |
244 | | - from the `input-values`. As shown below, this subscription will simply retrieve |
245 | | - the value associated with the `:foo` key in our db: |
246 | | - #!clj |
247 | | - (reg-sub |
248 | | - :query-id |
249 | | - (fn [db _] ;; :<---- trivial boilerplate we might want to skip over |
250 | | - (:foo db))) |
| 241 | + This sugary variation allows you to pass a function that will expect only one parameter, |
| 242 | + namely the `input-values` and entirely omit the `query-vector`. A typical `computation-function` |
| 243 | + expects two parameters which can cause unfortunate results when attempting to use |
| 244 | + clojure standard library functions, or other functions, in a functional manner. |
251 | 245 |
|
252 | | - This is slightly more boilerplate than we might like to do, |
253 | | - as we can use a keyword directly as a function, and we might like to do this: |
254 | | - #!clj |
255 | | - (reg-sub |
256 | | - :query-id |
257 | | - :foo) ;; :<---- This could be dangerous. If `:foo` is not in db, we get the `query-vector` instead of `nil`. |
| 246 | + For example, a significant number of subscriptions exist only to get a value |
| 247 | + from the `input-values`. As shown below, this subscription will simply retrieve |
| 248 | + the value associated with the `:foo` key in our db: |
258 | 249 |
|
259 | | - By using `:->` our function would not contain the `query-vector`, and any |
260 | | - missing keys would be represented as such: |
261 | | - #!clj |
262 | | - (reg-sub |
263 | | - :query-id |
264 | | - :-> :foo) |
| 250 | + #!clj |
| 251 | + (reg-sub |
| 252 | + :query-id |
| 253 | + (fn [db _] ;; :<---- trivial boilerplate we might want to skip over |
| 254 | + (:foo db))) |
265 | 255 |
|
266 | | - This form allows us to ignore the `query-vector` if our `computation-function` |
267 | | - has no need for it, and be safe from any accidents. Any 1-arity function can be provided, |
268 | | - and for more complicated use cases, `partial`, `comp`, and anonymous functions can still be used. |
| 256 | + This is slightly more boilerplate than we might like to do, |
| 257 | + as we can use a keyword directly as a function, and we might like to do this: |
| 258 | +
|
| 259 | + #!clj |
| 260 | + (reg-sub |
| 261 | + :query-id |
| 262 | + :foo) ;; :<---- This could be dangerous. If `:foo` is not in db, we get the `query-vector` instead of `nil`. |
| 263 | +
|
| 264 | + By using `:->` our function would not contain the `query-vector`, and any |
| 265 | + missing keys would be represented as such: |
| 266 | +
|
| 267 | + #!clj |
| 268 | + (reg-sub |
| 269 | + :query-id |
| 270 | + :-> :foo) |
| 271 | +
|
| 272 | + This form allows us to ignore the `query-vector` if our `computation-function` |
| 273 | + has no need for it, and be safe from any accidents. Any 1-arity function can be provided, |
| 274 | + and for more complicated use cases, `partial`, `comp`, and anonymous functions can still be used. |
269 | 275 |
|
270 | 276 | 3. A single sugary tuple of `:=>` and a multi-arity `computation-function` |
271 | | - #!clj |
272 | | - (reg-sub |
273 | | - :query-id |
274 | | - :=> computation-fn) |
275 | 277 |
|
276 | | - The `query-vector` can be broken into two components `[query-id & optional-values]`, and |
277 | | - some subscriptions require the `optional-values` for extra work within the subscription. |
278 | | - To use them in variation #1, we need to destructure our `computation-function` parameters |
279 | | - in order to use them. |
280 | | - #!clj |
281 | | - (reg-sub |
282 | | - :query-id |
283 | | - (fn [db [_ foo]] |
284 | | - [db foo])) |
| 278 | + #!clj |
| 279 | + (reg-sub |
| 280 | + :query-id |
| 281 | + :=> computation-fn) |
285 | 282 |
|
286 | | - Again we are writing boilerplate just to reach our values, and we might prefer to |
287 | | - have direction access through a parameter vector like `[input-values optional-values]` |
288 | | - instead, so we might be able to use a multi-arity function directly as our `computation-function`. |
289 | | - A rewrite of the above sub using this sugary syntax would look like this: |
290 | | - #!clj |
291 | | - (reg-sub |
292 | | - :query-id |
293 | | - :=> vector) ;; :<---- Could also be `(fn [db foo] [db foo])` |
| 283 | + The `query-vector` can be broken into two components `[query-id & optional-values]`, and |
| 284 | + some subscriptions require the `optional-values` for extra work within the subscription. |
| 285 | + To use them in variation #1, we need to destructure our `computation-function` parameters |
| 286 | + in order to use them. |
| 287 | +
|
| 288 | + #!clj |
| 289 | + (reg-sub |
| 290 | + :query-id |
| 291 | + (fn [db [_ foo]] |
| 292 | + [db foo])) |
| 293 | +
|
| 294 | + Again we are writing boilerplate just to reach our values, and we might prefer to |
| 295 | + have direction access through a parameter vector like `[input-values optional-values]` |
| 296 | + instead, so we might be able to use a multi-arity function directly as our `computation-function`. |
| 297 | + A rewrite of the above sub using this sugary syntax would look like this: |
| 298 | +
|
| 299 | + #!clj |
| 300 | + (reg-sub |
| 301 | + :query-id |
| 302 | + :=> vector) ;; :<---- Could also be `(fn [db foo] [db foo])` |
294 | 303 |
|
295 | 304 | The `computation function` is expected to take two arguments: |
296 | 305 |
|
|
301 | 310 |
|
302 | 311 | When `computation function` is called, the 2nd `query-vector` argument will be that |
303 | 312 | vector supplied to the `subscribe`. So, if the call was `(subscribe [:sub-id 3 :blue])`, |
304 | | - then the `query-vector` supplied to the computaton function will be `[:sub-id 3 :blue]`. |
| 313 | + then the `query-vector` supplied to the computation function will be `[:sub-id 3 :blue]`. |
305 | 314 |
|
306 | 315 | The argument(s) supplied to `reg-sub` between `query-id` and the `computation-function` |
307 | 316 | can vary in 3 ways, but whatever is there defines the `input signals` part |
|
413 | 422 | Syntactic sugar for both the `signal-fn` and `computation-fn` can be used together |
414 | 423 | and the direction of arrows shows the flow of data and functions. The example from |
415 | 424 | directly above is reproduced here: |
| 425 | +
|
416 | 426 | #!clj |
417 | 427 | (reg-sub |
418 | 428 | :a-b-sub |
|
524 | 534 | (defn clear-subscription-cache! |
525 | 535 | "Removes all subscriptions from the cache. |
526 | 536 |
|
527 | | - This function can be used at development time or test time. Useful when hot realoding |
| 537 | + This function can be used at development time or test time. Useful when hot reloading |
528 | 538 | namespaces containing subscription handlers. Also call it after a React/render exception, |
529 | 539 | because React components won't have been cleaned up properly. And this, in turn, means |
530 | 540 | the subscriptions within those components won't have been cleaned up correctly. So this |
|
759 | 769 | at the bottom of the panel. |
760 | 770 |
|
761 | 771 | Almost any user action (edit text, add new todo, remove a todo) requires a |
762 | | - complete reassessment of duplication errors and warnings. Eg: that edit |
| 772 | + complete reassessment of duplication errors and warnings. E.g. that edit |
763 | 773 | just made might have introduced a new duplicate, or removed one. Same with |
764 | 774 | any todo removal. So we need to re-calculate warnings after any CRUD events |
765 | 775 | associated with the todos list. |
|
0 commit comments