【Clojure】re-frame for SPA

栏目: 编程语言 · Clojure · 发布时间: 5年前

内容简介:事件来源:用户输入、用户点击、定时器、远程调用响应等。事件作为一个数据被投入到类似于事件总线的队列,其数据结构为:

re-frame介绍

re-frame 是一个帮助我们快速开发WEB单页面应用的框架,是一个基于数据驱动的框架。其主要流程是如下的一个永无止境大循环:

【Clojure】re-frame for SPA

dispatch——事件分发

事件来源:用户输入、用户点击、定时器、远程调用响应等。事件作为一个数据被投入到类似于事件总线的队列,其数据结构为:

[event-id event-arg1 event-arg2 ...]

re-frame事件分发函数:

(re-frame.core/dispatch [event-id event-arg1 event-arg2])

event-handler——事件处理

对于分发过来的事件,re-frame会根据事件ID(`event-id)找到注册的事件处理函数,进行处理。event-handler是整个应用的业务核心,re-frame使得事件处理过程变成了一个纯函数(稳定、可测试)。

(defn remove-item
  "删除元素事件处理"
  [coeffects event]               ;; `coeffects` holds the current state of the world.  
     (let [item-id (second event)         ;; extract id from event vector
           db      (:db coeffects)]       ;; extract the current application state
       {:db  (dissoc-in db [:items item-id])
        :request {:request-id :some-thing}}))))

;; 注册事件处理
(re-frame.core/reg-event-fx   ;; a part of the re-frame API
  :remove-item                   ;; event id
  remove-item)

事件处理函数的输入参数: [coeffects event]

  • coeffects:包含了事件处理函数执行时当前"世界"的全部状态,包括 db(应用的本地状态) 以及其他事件处理上下文数据,如当前时间,随机数等...

    {:db app-state ;; 当前app的状态,re-frame默认设置的
     :now 事件执行时的时刻 ;; 需要自定义注册
     :random-num 随机数  ;; 需要自定义注册
     ...
     }
  • event:事件,参见上述 事件数据结构

事件处理函数拿都输入参数中的数据,通过计算之后,输出effects,如:

{:db new-db ;; 更新应用状态的效果
 :request request-data ;; 远程调用的效果
 :cookie cookie-data ;; 更新cookie的效果
 :timer timer-data ;; 启动或关闭定时器的效果
 ...}

即用一个数据结构来描述事件处理之后要做的一些"副作用"操作,而不是直接在事件处理函数中调用这些副作用操作,如修改数据库,执行远程调用,修改cookie的值,这样会使得事件处理函数变成非纯函数。

PS:上述结构中,key为effect的ID,标志一类effect。

effects handler——效果处理

re-frame会根据effect id 找到事先注册好的效果处理函数,对效果进行处理。如对于 :db 这个默认的效果,re-frame会用新的db替换旧的db(这是re-frame的默认处理)。对于那些自定义效果,则需要注册自定义处理函数,以远程调用效果request为例:

(defn request-effect-handler
  "远程调用效果处理函数"
  [{:keys [event params resp-event] :as request-data}]
    (case event
      :query-user-balance
      ;; 模拟远程调用
      (js/setTimeout #(re-frame/dispatch [resp-event 20000]) 5000)))

;; 注册效果处理函数
(re-frame/reg-fx
  :request         ;; effect id
  request-effect-handler)

效果处理完之后,应用的状态被更新改变。

query——查询应用状态中用于显示的相关数据

应用状态被更新之后,负责显示的视图层会从新的状态中,查找出它展示所需要的数据:

(defn query-fn
    "定义从应用状态db中查询出所需数据函数"
  [db]         ;; db is current app state
  (:items db))   ;; not much of a materialised view

;; 注册查询函数
(re-frame/reg-sub
  :query-items ;; 查询ID :query-id
  query-fn)

;; 因为clojure中关键字也可以作为函数,所以上面的代码等价于:
(re-frame/reg-sub :query-items :items)

view——生成新的视图

视图层根据query-id订阅所需要的数据,然后根据数据生成新的视图:

(defn items-view
  "定义视图生成函数"
  []
  (let [items  (re-frame/subscribe [:query-items])]  ;; source items from app state
    [:div (map item-render @items)]))   ;; assume item-render already written

subscribe 函数向应用状态中订阅query-id(:query-items)指定的数据,每当应用状态中这个数据发生改变时,都会重新生成新的视图。

Reagent/React——渲染视图

生成的新的视图会被重新渲染到DOM,展现给用户:

(reagent/render [views/items-view] (.getElementById js/document "app"))

示例Demo1—— re-frame simple template

示例Demo2—— Demo1重构后的版本

为什么重构?

re-frame

re-frame核心设计思想:数据

db

以上所述就是小编给大家介绍的《【Clojure】re-frame for SPA》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

引爆点

引爆点

【加】马尔科姆•格拉德威尔(Malcolm Gladwell) / 钱清、覃爱冬 / 中信出版社 / 2014-4 / 36.00元

《引爆点》是《纽约客》怪才格拉德威尔的一部才华横溢之作。他以社会上突如其来的流行潮为切入点,从全新角度探索了控制科学和营销模式。他认为,思想、行为、信息及产品常会像传染病暴发一样迅速传播。正如一个病人就能引起全城流感;几位涂鸦爱好者能在地铁掀起犯罪浪潮;一位满意而归的顾客还能让新开张的餐馆座无虚席;发起小规模流行的团队能引发大规模流行风暴。这些现象均属“社会流行潮”,它达到临界水平并爆发的那一刻,......一起来看看 《引爆点》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

随机密码生成器
随机密码生成器

多种字符组合密码