allow observers on app-state leaf nodes
This commit is contained in:
parent
8b564f09a7
commit
712a657846
@ -45,11 +45,20 @@
|
||||
|
||||
(let [s (observable.new {:foo {:bar 43}})]
|
||||
(var win false)
|
||||
;; observers live on subtrees, not individual nodes
|
||||
(s:observe [:foo] #(set win true))
|
||||
;; observer on leaf
|
||||
(s:observe [:foo :bar] #(set win true))
|
||||
(s:update [:foo :bar] 42)
|
||||
(expect (and win)))
|
||||
|
||||
(let [s (observable.new {:foo {:bar 43}})]
|
||||
(var win false)
|
||||
;; observer on subtree
|
||||
(s:observe [:foo] #(set win true))
|
||||
(s:update [:foo :bar] 42)
|
||||
(expect (and true win)))
|
||||
|
||||
|
||||
|
||||
(let [s (observable.new {:foo {:bar {:baz 43}}})]
|
||||
(var win 0)
|
||||
;; observers on ancestor trees are called after child trees
|
||||
|
@ -3,32 +3,40 @@
|
||||
(fn concat [dest src]
|
||||
(table.move dest 1 (# dest) (# src) src))
|
||||
|
||||
(fn update [data self path value]
|
||||
(fn update [data path value vivify?]
|
||||
(let [[first & rest] path]
|
||||
(if (next rest)
|
||||
(update (. data first) self rest value)
|
||||
(tset data first value))
|
||||
(if data._subscribers
|
||||
(each [_ f (pairs data._subscribers)] (f)))))
|
||||
|
||||
(fn get [data self path]
|
||||
(let [[first & rest] path]
|
||||
(if (not first) data
|
||||
(next rest) (get (. data first) self rest)
|
||||
(. data first))))
|
||||
|
||||
(fn observe [data self path fun]
|
||||
(let [el (get data self path)]
|
||||
(when el
|
||||
(if el._subscribers
|
||||
(table.insert el._subscribers fun)
|
||||
(tset el :_subscribers [fun])))))
|
||||
(do
|
||||
(if (and vivify? (not (. data first)))
|
||||
(tset data first {}))
|
||||
(update (. data first) rest value))
|
||||
(tset data first value))))
|
||||
|
||||
(fn new [data]
|
||||
{
|
||||
:observe (partial observe data)
|
||||
:update (partial update data)
|
||||
:get (partial get data)
|
||||
})
|
||||
(let [observers {}
|
||||
key [:obs]]
|
||||
(fn get [data path]
|
||||
(let [[first & rest] path]
|
||||
(if (not first) data
|
||||
(next rest) (get (. data first) rest)
|
||||
(. (or data {}) first))))
|
||||
|
||||
(fn publish [observers path]
|
||||
(let [[first & rest] path
|
||||
os (. (or observers {}) first)]
|
||||
(if (and (next rest) (next os)) (publish os rest))
|
||||
(match os
|
||||
{key list} (each [_ f (pairs list)] (f)))))
|
||||
|
||||
(fn observe [observers path fun]
|
||||
(let [el (get observers path)]
|
||||
(if el
|
||||
(table.insert (. el key) fun)
|
||||
(update observers path {key [fun]} true))))
|
||||
{
|
||||
:observe #(observe observers $2 $3)
|
||||
:update #(do (update data $2 $3) (publish observers $2))
|
||||
:get #(get data $2)
|
||||
}))
|
||||
|
||||
{: new }
|
||||
|
Loading…
Reference in New Issue
Block a user