This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-01-30
Channels
- # arachne (23)
- # bangalore-clj (2)
- # beginners (64)
- # boot (20)
- # cider (3)
- # clara (11)
- # cljs-dev (29)
- # cljsrn (10)
- # clojure (143)
- # clojure-brasil (4)
- # clojure-dev (22)
- # clojure-dusseldorf (3)
- # clojure-italy (26)
- # clojure-sanfrancisco (13)
- # clojure-seattle-old (2)
- # clojure-spec (15)
- # clojure-uk (27)
- # clojured (1)
- # clojurescript (52)
- # core-async (13)
- # cursive (2)
- # datomic (106)
- # fulcro (45)
- # garden (1)
- # graphql (11)
- # hoplon (98)
- # jobs (11)
- # juxt (7)
- # keechma (2)
- # leiningen (36)
- # off-topic (39)
- # parinfer (13)
- # re-frame (34)
- # reagent (5)
- # ring (1)
- # rum (4)
- # shadow-cljs (83)
- # sql (1)
- # timbre (1)
- # unrepl (49)
- # vim (1)
- # yada (42)
@hiskennyness mmm how do we write that though...
@thedavidmeister I use a dynamic state variable and rebind when I want to create a local state scope
what does that look like?
(ns degree9.state)
(def ^:dynamic *data* (javelin.core/cell nil))
(ns other.ns
(:require [degree9.state :as state]))
(defn mkstate [input]
(binding [state/*state* (data.ns/get-data)]
(let [...]
;;everything in here that has a cell which referenced state/*state* we get scoped data, this lets us create consistent state cells
)))
why not just make a fn that returns a new data cell?
also i meant "how do we write that in a convincing way on the homepage" 😛
thats what get-data
does
but this is interesting
i don't really use binding
so i'm wondering what the advantage is over just passing cells into fns as args
runtime binding
some state has to be bound at runtime, also you get state-isolation between elements in -tpl
but hoplon also has it’s own runtime binding in the hoplon.binding
ns provided by @micha
i don't think i've run into issues with state not being isolated
you also get to modify “nested” state without directly passing it around
i think i need an example of the problem before i understand the solution
for example @thedavidmeister ^
in that example config
is binding
+`let`
the best example on that page is probably how the router works, there is a router which can be dynamically bound so all the components use the router but dont actually care what it is implemented by, the implementation is bound at runtime
right so you're setting *admin-menu*
to a cell somewhere near the top of your app's tree structure
then all the children can use it if they want
right without passing the variable around
hah, not sure if i love it or hate it 😛
there is a common api which all the components agree on, ie the core “state”
so it is very convenient from an app perspective
but would make things less portable from a lib perspective
sorta, the idea is you build App domains around it
well if you went and stuck
(defelem card-button [attr kids]
(let [id (:id attr *admin-menu*)]
(div :id "card-admin-button" :class [:mdl-button--admin_button-container]
(btn/button :id id :fab true :class [:mdl-color--primary]
(i :class [:material-icons :mdl-color-text--white] "more_vert"))
(menu/menu :top-right true :data-mdl-for id
(menu/menu-item "Admin Item")))))
so libraries are wrapped within a ns, then you implement a namespace per provider
into a lib
i have to manage a *admin-menu*
multiply that by a few dozen libs and it would be annoying
the blog was a good example of how quickly the bindings can grow and be annoying but the cool thing is that you get the ability to swap state providers at a single site instead of throught an application simply by including the ns and replacing the binding
yes, well my approach is just passing everything through
because i got burned by my app having lots of "reaching out" to state inside hoplon elements
so i did a big refactor
but i can see a few places where it would be convenient to use your binding approach
yeah thats what I usually do too, this was mostly an experiment, I dont know the runtime costs of doing all this rebinding
well for me it was about testability
but the binding approach can satisfy that i think
for example, i have a project-id
that lots of things use, and it comes from the route
that could be a binding
it makes sense to me when you have app-specific components that are deeply nested and rely on info derived directly from things that are already inherently global, like the route
@thedavidmeister we could make running the tests as simple as binding the provider
(binding [hoplon.test/*provider* hoplon.jquery]
(require [hoplon.test/*provider*]))
and calling all the tests with a function we can wrap
yeah, or is there like a "before hook" that we can call once?
for the whole suite
yeah thats kinda what is possible with the elem!
pr
cool, will it work in cljs though?
i don't think require
is a fn in cljs
only clj
since elem!
implements invoke you can override it
but I dont think we can do much at compile time without either a macro or compiler var
i do wonder if we'll need providers forever...
seems like a lot of what hoplon does should be supported by browsers in a reasonably standard way
or maybe we just namespace the "extra features" from the provider at the attr level
would :jq/click
be the worst?
i'm not 100% sold on the approach of pulling in a namespace and having that implicitly rewire all the core internals
again, it makes writing and sharing libs harder
I dont think we need the to do anything implicitly
we already do though
(:require hoplon.jquery)
implements a whole bunch of stuff
well only the “extra” features
as soon as it is included it changes how core works
yeah, what i mean is that if i write an app and use hoplon.jquery
all the way through
that could easily be fixed by prefixing the current provider attributes
then i want to split out some cool functionality into a lib, then how do i do that easily?
i wouldn't be confident that it works with any old provider, because i can't test that
and i wouldn't want to include hoplon.jquery
because then i'd blow away whatever provider you were using
yeah vendor prefixes are probably a standard we should implement since the support has been around since v7.0
i mean look at us scratching our head over just testing core's own functionality
way harder to take that into the wild for random libs floating around
and things like adding/removing attributes, adding event handlers, basic DOM manipulation, triggering events...
all that shouldn't need a provider
if you want a :toggle
go ahead and use jquery as :jq/toggle
if you want to add a class to an element, well that should just be a simple fn call in core
@thedavidmeister yeah the basics are provided by hoplon core already, but most events arnt provided
well yes and no
they are provided but then they get blown away when you pull a provider in
which you inevitably have to do because events
@flyboarder i'll put a tx up, we can come back to this at some point 🙂
@hiskennyness mind if i paste what you said into the github thread?
i mean go for it
changing the way providers work is not a BC change, so i'm thinking a candidate for an 8.0
release...
@thedavidmeister Search me. 🙂 How many folks have even coded up an FSM in anger? I think these spreadsheet and FSM analogies work only after a series of concrete examples have manifested the elegant effectiveness of dataflow. Then we go big with the parallels to spreadsheets and FSMs. I am trying to catch my tendency to explain dataflow to myself, who already has experienced its power and is trying to understand it. Those explanations are rationally sound but viscerally unbound.
@thedavidmeister Yes, posting to the GitHub thread will be fine.
@hiskennyness the localness of the scope and independence of components is good, also "programming with values" rather than "programming with time" is good
"programming with time" i like it, as the opposite of programming with values