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}})]
|
(let [s (observable.new {:foo {:bar 43}})]
|
||||||
(var win false)
|
(var win false)
|
||||||
;; observers live on subtrees, not individual nodes
|
;; observer on leaf
|
||||||
(s:observe [:foo] #(set win true))
|
(s:observe [:foo :bar] #(set win true))
|
||||||
(s:update [:foo :bar] 42)
|
(s:update [:foo :bar] 42)
|
||||||
(expect (and win)))
|
(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}}})]
|
(let [s (observable.new {:foo {:bar {:baz 43}}})]
|
||||||
(var win 0)
|
(var win 0)
|
||||||
;; observers on ancestor trees are called after child trees
|
;; observers on ancestor trees are called after child trees
|
||||||
|
@ -3,32 +3,40 @@
|
|||||||
(fn concat [dest src]
|
(fn concat [dest src]
|
||||||
(table.move dest 1 (# dest) (# src) src))
|
(table.move dest 1 (# dest) (# src) src))
|
||||||
|
|
||||||
(fn update [data self path value]
|
(fn update [data path value vivify?]
|
||||||
(let [[first & rest] path]
|
(let [[first & rest] path]
|
||||||
(if (next rest)
|
(if (next rest)
|
||||||
(update (. data first) self rest value)
|
(do
|
||||||
(tset data first value))
|
(if (and vivify? (not (. data first)))
|
||||||
(if data._subscribers
|
(tset data first {}))
|
||||||
(each [_ f (pairs data._subscribers)] (f)))))
|
(update (. data first) rest value))
|
||||||
|
(tset data first value))))
|
||||||
(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])))))
|
|
||||||
|
|
||||||
(fn new [data]
|
(fn new [data]
|
||||||
{
|
(let [observers {}
|
||||||
:observe (partial observe data)
|
key [:obs]]
|
||||||
:update (partial update data)
|
(fn get [data path]
|
||||||
:get (partial get data)
|
(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 }
|
{: new }
|
||||||
|
Loading…
Reference in New Issue
Block a user