Fork me on GitHub
#re-frame
<
2020-05-21
>
nprbst00:05:52

Ahhh...things are starting to come into focus. Thank you. That helped.

Alexander Knemeyer12:05:46

Hi all. I'm relatively new to clojurescript/re-frame and am having trouble deciding how best to structure/model a certain type of relationship between data. I'll use the flowchart in here: https://en.wikipedia.org/wiki/Flowchart#/media/File:LampFlowchart.svg as an example because it's very similar to what I'm trying to model (I'm talking about the svg blocks and lines, not what the chart is modelling) So we have a map of blocks (each of which has an id, [x y] coordinate, etc) which can be dragged around and so on. Then, we have the connections which have their own state, but which also depend on the state of the blocks for the purpose of drawing them onto a canvas. Eg the line with id = 4 depends on the [x y] positions of blocks with id = 1, 2 Right now my db is structured something like,

(rf/reg-event-db
 :initialize
 (fn [_ _]
   {:blocks {}
    :connections {}}))
with blocks and connections between something like,
(defrecord Connection [id block-start-id block-end-id other-state])
(defrecord Block [id x y])
I know how to subscribe/dispatch events to do with the block, but Is there a recommended way of doing the same with connections? I would need to update the connection as the block moves. I'm sure I'm missing something obvious - I'm super new to this. Thanks!

p-himik12:05:59

Each connection is defined in terms of IDs of blocks that it connects together. If one of the blocks moves, the ID is not changed, is it? If so, then the connection should be left as is, that's it.

Alexander Knemeyer12:05:47

I mean that the connection needs the xy data of the block in order to be rendered

p-himik12:05:38

A connection is a data structure, it has no behavior by itself. What does "the connection needs" mean?

p-himik12:05:10

If some fn has a connection and the storage of all blocks, it can easily extract the blocks connected together by that connection.

Alexander Knemeyer12:05:17

I could previously extract the blocks from a blocks RAtom, so would each connection just subscribe to changes in the blocks it depends on?

p-himik12:05:24

> would each connection just subscribe So a connection is not just a record but also a view? If so, then yes. Or you can subscribe just to the :blocks and pass it down to each connection. In general, there are two ways of giving the views the data that they require - you either subscribe to the data or you pass it down from the parent component. Or a mix of both.

Alexander Knemeyer12:05:35

Yes the connections are views as well! Exactly as if you were to draw the flow diagram I linked earlier. Last question then - while i could just subscribe to :blocks as a whole, ideally each connection would subscribe to varying blocks in the map. Since there are a varying number of blocks and connections, I'd have to set up those subscriptions dynamically (like :block-4 etc). Is that the regular way of doing that, or is there a a built in way of handling cases like that?

p-himik12:05:04

No, not like :block-4. Like (subscribe [:block 4]). The 4 becomes a subscription parameter.

p-himik12:05:32

(reg-sub :block (fn [db [_ block-id]] (get-in db [:blocks block-id))) or something like that.

Alexander Knemeyer12:05:14

ahhhhh of course! I knew there was something wrong with what I was saying but I can't believe it was that silly. Thank you for the detailed and quick help, I really appreciate it. Feeling a lot more confident about this now Also, I don't know if you work on re-frame, but it's been great to work with so far. I really appreciate that too

👍 4
kirill.salykin15:05:28

Hi I am implementing form each field of the form has a sub (generalized)

(rf/reg-sub :form/field
            (fn [db [_ form-id field]]
              (get-in db [:form/form form-id :fields field])))
On render, field sub derefed and used like this
(let {:keys [value error touched?]} @(rf/subscribe [:form/field form-id name])
<hiccup>)
but every field is re-rendered on change of one field (eg if you change email both email and password will be rerendered) is it something expected ? is it possible that only changed field is rerendered? thanks

mikethompson21:05:08

@kirill.salykin Given the snippet provided, I wouldn't expect all fields to get re-rendered

mikethompson21:05:41

Is each field in its own component?

kirill.salykin21:05:26

no, it is not... clear, thanks!