Skip to content

Instantly share code, notes, and snippets.

@kumavis
Created February 19, 2015 21:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kumavis/2bb0e66a32958ce0612f to your computer and use it in GitHub Desktop.
Save kumavis/2bb0e66a32958ce0612f to your computer and use it in GitHub Desktop.
10:46 <kumavis> maybe components could have some generic channel-generating hooks ?
10:46 <kumavis> render() { return inputBox( state.label, state.channels.bindValue('label') ) }
10:47 <kumavis> which could simplify to inputBox( state, 'label' )
10:47 <kumavis> so i dont have to create a channel that only updates a value directly passed in
10:48 <kumavis> right now i have to do inputBox(state.newIdentityAddress, state.channels.updateNewIdentityAddress)
10:48 <kumavis> function updateNewIdentityAddress(state, data) {
10:48 <kumavis> state.newIdentityAddress.set(data.text)
10:48 <kumavis> }
10:48 <kumavis> its just a lot of code to do one simple thing i feel
10:56 ⇐ alexandergugel quit (~alexander@208.66.27.18) Remote host closed the connection
10:56 <neonstalwart> or… if you're comfortable with it, you can pass an observ from the parent to the child
10:57 <neonstalwart> inputBox({ value: state.newIdentityAddress })
10:57 → alexandergugel joined (~alexander@208.66.27.18)
10:57 <neonstalwart> then inputBox just does state.value.set( … )
10:57 <neonstalwart> which is effectively parentState.newIdentityAddress.set( … )
10:58 <neonstalwart> pick your poison - more events or sharing observables
10:58 <neonstalwart> observe vs inject :)
10:59 <neonstalwart> kumavis (just mentioning in case you didn't see my reply)
11:00 <kumavis> ah thanks
11:01 <kumavis> yeah right now im doing pojo state in all my renders
11:01 <kumavis> though sharing observables is less messy
11:02 <neonstalwart> yeah - events/inputs give you a 3rd option… state.inputBox.events.change(state.newIdentityAddress.set)
11:02 <neonstalwart> you can't do that with channels
11:02 <kumavis> oo hmmm
11:04 <neonstalwart> just to clarify… inputBox({ value: state.newIdentityAddress }) is in your state, not in your render
11:05 <neonstalwart> i'm saying that because i'm not sure what "yeah right now im doing pojo state in all my renders" is in response to
11:05 <neonstalwart> all my renders are plain objects too
11:08 → reqshark and tixz joined ⇐ hareth and ashnur quit ↔ tphummel nipped out
12:21 <kumavis> ah gotcha
12:22 <kumavis> i do feel something as simple as an input should not need to be defined in two places (state and render)
12:23 → arianvp___ joined (~arian@125pc241.sshunet.nl)
12:23 <kumavis> i mean in your case it needs to be in order to set it up, but it just feels like we're making a lot of work for our selves
12:24 <kumavis> not sure what the happy middle ground is
12:29 <neonstalwart> yeah, i'd be glad to do less work if possible. i've spent the past 9 months building an app with mercury. admittedly, i put a lot of my thinking into the first few months and haven't had a chance to come back and revisit the patterns in light of the pain-points that i've noticed over the past 9 months.
12:30 <kumavis> those are some valuable insights
12:30 <neonstalwart> during that time, mercury evolved too but i have not had the time to take that into account either. that's part of why i use events - because channels didn't exist - but to use channels i'll have to change some of the fundamentals of what i've done.
12:30 <neonstalwart> and i'm not sure channels give me what i need
12:41 <kumavis> so i have a best-practices q
12:41 <kumavis> in the app im managing esssentially bitcoin wallets
12:41 <kumavis> the wallet address key doesnt change
12:41 → thealphanerd joined (~thealphan@pdpc/supporter/student/thealphanerd)
12:41 <kumavis> but the value in that address does
12:41 <kumavis> and i need to do network i/o to find out what it is
12:42 <kumavis> where should the network i/o happen? should the value it returns be stored in the state tree?
12:43 <neonstalwart> kumavis: i think you need to store the value in the state tree
12:43 <neonstalwart> so, when it updates, it triggers a render
12:44 <kumavis> sounds good, can include a timestamp to for expiry
12:44 <neonstalwart> as for network i/o, i usually do that in my handlers for events
12:45 <neonstalwart> i definitely don't do it in render - that's probably an obvious thing to say, but i said it :)
12:45 <neonstalwart> i sometimes do it in my constructor/factory
12:46 <kumavis> is there a standardized pattern for 'computed properties'? values based on state but that dont need to be stored redundantly?
12:46 <neonstalwart> i was just about to mention something like that… hg.watch(state.foo, respond)
12:46 <neonstalwart> or hg.computed([ state.foo, state.bar ], respondToEitherChange)
12:47 <kumavis> gotcha 'observ/computed'
12:47 <neonstalwart> hg.watch is basically
12:47 <neonstalwart> respond(state.foo()); // handle the current value
12:47 <neonstalwart> state.foo(respond); // handle future values
12:47 <neonstalwart> yeah
12:48 <neonstalwart> it returns another observ but you can ignore it or use it - up to you
12:48 ⇐ tixz quit (~tixz@82.211.209.116) Remote host closed the connection
12:48 <kumavis> k cool
12:49 <kumavis> neonstalwart: if you'll allow me one more
12:50 <neonstalwart> absolutely
12:50 <kumavis> best way to share state between two components
12:50 <neonstalwart> i'm waiting on some CI to finish :)
12:50 ⇐ alexandergugel quit (~alexander@208.66.27.18) Remote host closed the connection
12:50 <kumavis> app has a list of identities
12:50 <kumavis> we hand this off to the identity management component, which can add and remove them
12:50 <kumavis> and we also hand it off to the wallet view
12:50 <kumavis> which shows balances for each wallet
12:51 <neonstalwart> ok, i have an app.user which is the current user - i tend to pass this observ around as needed and then in one place in the app, i can change the user and everything should respond
12:51 → alexandergugel joined (~alexander@208.66.27.18)
12:51 <neonstalwart> i pass it around from the top down
12:52 <kumavis> https://www.irccloud.com/pastebin/9Px3yw1k
12:53 → tixz joined (~tixz@82.211.209.116)
12:53 <kumavis> uh
12:53 <kumavis> https://gist.github.com/kumavis/323311f86b5d4f5ae81e
closekumavis — 19 Feb 2015
12:53 <neonstalwart> kumavis: yeah, that's it.
12:54 <kumavis> so one thing i notice is that when serializing to pojo, it is duplicated
12:54 ⇐ tixz quit (~tixz@82.211.209.116) Remote host closed the connection
12:55 <neonstalwart> oh, are you wrapping the values in observ again?
12:55 <neonstalwart> (or perhaps something you're using is doing that for you?)
12:55 <neonstalwart> is that what you mean by duplicated?
12:55 <kumavis> i dont think Struct does that
12:56 <neonstalwart> no, it doesn't
12:56 <neonstalwart> that's what i use
12:56 <neonstalwart> you need to specifically wrap values, struct just wraps the top-level of the object
12:59 <kumavis> https://gist.github.com/kumavis/548eb02df34608c9f896
closekumavis — 19 Feb 2015
12:59 <kumavis> thats the serialized output
13:00 <kumavis> notice the identities array repeated
13:00 <neonstalwart> oh right, yeah it will be
13:00 <neonstalwart> the serialized output matches the structure of your state
13:00 <kumavis> i mean i can live with that for now
13:01 <kumavis> but if i had some massive state
13:01 <kumavis> that would be silly
13:01 <neonstalwart> to some extent you may not be able to avoid this
13:02 <neonstalwart> especially if you're going to use hg.partial
13:02 <kumavis> maybe if i had some beefy model
13:03 <kumavis> i could store the model in a ModalStore, and just reference its id in the states
13:03 <kumavis> but that sounds like a mess
13:03 <neonstalwart> let's say that your list of identities changes and you find a way not to have it in fromSelect. if the identities change then your fromSelect state will be the same object and if you're using hg.partial(Select.render, state.fromSelect), you won't get a new rendering
13:03 <neonstalwart> this is why i don't serialize my state
13:03 ↔ cheezwhiz popped in
13:04 <neonstalwart> i keep domain models serializable and derive my viewModels/state from that
13:06 <arianvp___> It's funny how I look for css transition stuff and I discover you guys are discussing this since only for a few days
13:06 <arianvp___> :D
13:07 <kumavis> mercury is not funded by global mega corp, and is not in use at a global mega corp
13:07 → hareth joined (~kapit@ram75-1-78-192-223-109.fbxo.proxad.net)
13:08 <arianvp___> I mean. that's cool. that I hit a problem and other people are facing it at the exact same time. somehow a bit magical.
13:09 <kumavis> hmm, webapps are hard
13:09 → tixz joined (~tixz@82.211.209.116)
13:09 <arianvp___> :)
13:10 <kumavis> arianvp___: what are you trying to do?
13:10 <neonstalwart> arianvp___: css transitions are something we've been challenged with since the start
13:10 <arianvp___> I'm trying to make a slideshow component
13:10 <arianvp___> which fades inbetween two images
13:10 <neonstalwart> so, we are hitting it at the exact same time because we are *still* facing it after months of trying to figure it out :)
13:10 <arianvp___> ah
13:10 <arianvp___> how did react 'solve' this?
13:10 <arianvp___> can't we eavesdrop there?
13:11 <neonstalwart> arianvp___: if you read the comment i linked to, it is how react solved it
13:11 <neonstalwart> (the comment i linked to on github)
13:12 <arianvp___> ah yeh. but that's only for entry animations right. (though that's probably all I need)
13:13 <neonstalwart> arianvp___: no, the link to react solves removals too
13:14 <neonstalwart> arianvp___: https://github.com/Matt-Esch/virtual-dom/issues/104#issuecomment-73732749 has a link to http://facebook.github.io/react/docs/animation.html which is about ReactCSSTransitionGroup
13:15 <arianvp___> awesome :)
13:15 <arianvp___> lets see if I can get this example ported to purescript and elm
13:16 <dreamdust> What's the problem with CSS transitions exactly? Your CSS classes are properties of the vtree which is simply a function of your state. State changes, class changes, and then a transition happens.
13:16 <neonstalwart> dreamdust: when an element is removed, you typically lose the state too
13:16 <arianvp___> ^
13:17 <neonstalwart> with an animation, you want to hold the element long enough to transition it out of the view
13:17 <neonstalwart> so, you need a controller that understands how to remove something later even but make the state look like it was already removed
13:17 <dreamdust> Then you actually have another state you're not dealing with. You have a "being removed" view.
13:18 <dreamdust> but I see the problem now
13:18 ⇐ hareth quit (~kapit@ram75-1-78-192-223-109.fbxo.proxad.net) Quit: hareth
13:18 <dreamdust> but its a problem of standardization not really CSS transitions?
13:18 <dreamdust> You just want this to work the same way across different people's code bases?
13:19 <neonstalwart> dreamdust: yes, you likely will need to use a widget which can hold it's own state AND manipulate the DOM without breaking virtual-dom
13:19 <neonstalwart> dreamdust: it's not so much standardization - it's finding at least one way to do it first :)
13:19 <neonstalwart> then we can work on refining and standardizing (if needed)
13:20 <neonstalwart> …and it's not that there isn't a way. it's just that nobody has sat down and worked through it with a complete example
13:21 <neonstalwart> also, this controller widget needs to be a container so it can control adding/removing elements. you won't achieve this properly by trying to make an item controller that does this because the item can't remove itself from the parent
13:21 <dreamdust> This reminds me that I've been feeling lately like everyone wants to use "components" as the abstraction to build web apps, yet its not a first-class abstraction that mercury is built around
13:22 → ChrisPartridge joined
13:22 <neonstalwart> dreamdust: why do you say mercury isn't built around it? what alternative do you suggest for managing complexity? components are a great way to decompose a UI.
13:22 <dreamdust> with things like CSS animations… it starts getting into "lifecycle" issues
13:23 <dreamdust> something you normally deal with using a component
13:23 <dreamdust> mercury has no such concept
13:24 <neonstalwart> part of what i like about mercury is that it doesn't dictate mercury.Component( … )
13:24 <neonstalwart> instead, it gives you the pieces to build upon to make your own components which can be as loose or formal as you need.
13:25 <neonstalwart> i think it still encourages components - or at least enables them.
13:25 <dreamdust> with CSS transitions that seems like that modularity is more of a limitation
13:26 — dreamdust shrugs
13:26 <neonstalwart> i guess i don't see how modularity affects that.
13:27 <neonstalwart> it's the nature of virtualizing the DOM which makes CSS transitions difficult - which is independent of whether or not you use components to build your app.
13:34 → hareth joined (~kapit@ram75-1-78-192-223-109.fbxo.proxad.net)
13:34 <kumavis> i feel that if mercury was more opinionated about what a component was, and what its standard interfaces are ( e.g. .render() ) it would be easier to build reusable pieces and share with the community
13:35 <kumavis> maybe its not true
13:35 <neonstalwart> i agree… i think it's just too early to do it while we still haven't fleshed out the answers to things like channels/inputs/serializing, animations/transitions
13:36 <neonstalwart> to me, mercury still doesn't feel ready to start to lock in a pattern for components
13:37 <neonstalwart> modals/popovers/dynamically embedding content in another component is another one of the things i think needs to be considered
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment