Fork me on GitHub
#hoplon
<
2016-03-22
>
thedavidmeister09:03:31

@levitanong: yay for starting the defelem docs, I’m going to add a little bit to it as well, including micha’s example from the forum post I linked in the github issue

thedavidmeister09:03:27

i’m just going to add some more introductory information too

thedavidmeister09:03:59

like “what is an element?” and “what should I return?"

dm312:03:33

@levitanong: I've encountered the first problem with switch-tpl - doesn't play well when placed inside loop-tpl: merge-kids https://github.com/hoplon/hoplon/blob/master/src/hoplon/core.cljs#L82 wants to append an element which has to be a DOMElement, while it's really a Cell

dm312:03:02

now thinking - why does this happen if Hoplon seems to be overriding the appendChild function on the Element prototype

dm312:03:10

with something that can handle Cells as weel

dm312:03:25

in my case it seems the original appendChild is being called

levitanong12:03:37

@dm3: Is the switch-tpl inside a div?

dm312:03:55

nope, (loop-tpl ... (switch-tpl ...))

levitanong12:03:59

switch-tpl is a bit like loop-tpl. it needs a “real” elem to bind in

dm312:03:26

do you know the reason why?

dm312:03:36

because it seems like it should work from the code

levitanong12:03:40

(div
  (loop-tpl :bindings [a as]
    (div
      (switch-tpl …))))

levitanong12:03:35

as for why, it should be in the hoplon docs. lemme check.

levitanong12:03:24

afaik, you cannot nest a loop-tpl inside a loop-tpl without placing a div in between

levitanong12:03:58

it doesn’t actually say why, but i think @micha explained it to me long ago, and I just forgot 😛

dm312:03:42

yeah, I see something on the wiki

dm312:03:20

so it seems my initial interpretation was wrong

levitanong12:03:29

@dm3 Your interpretation looks correct though, in the sense that the problem seems to lie in the fact that it returns a cell instead of an element. But I fail to see a way by which we can work around this, because then we’d have to wonder how nesting a cell in a cell would work 😛

levitanong12:03:55

Oh wow, you were really thorough here! this is great 😄

thedavidmeister12:03:04

@levitanong: i just took what you and micha had written previously, then added all the things i learned from the chat room simple_smile

micha20:03:48

@dm3: re: your question yesterday about cell= children

micha20:03:03

> I'm guessing you had usecases in Adzerk where you had to generate DOM conditionally, e.g. different forms based on some condition type. How did you handle that, given that (cell= (cond a (form-a) b (form-b))) is not recommended due to potentially generated garbage.

micha20:03:24

we really don't encounter that at all

micha20:03:47

whenever we end up there we always end up refactoring it to something simpler and it goes away

dm320:03:24

interesting

micha20:03:44

the place where you start to need it is dynamic tree structures

micha20:03:57

like when you don't know what will be on the page basically

micha20:03:25

but i haven't yet run into that in a real-world application

dm320:03:28

yeah, I have a case like that

micha20:03:42

where you start to get into that territiroy is like a tree view of a directory structure

micha20:03:46

things like that

dm320:03:49

it's kind of solved with switch-tpl

micha20:03:58

like you don't know in advance how deep it will be, etc

micha20:03:05

so it looks like loop-tpl won't work there

dm320:03:16

I have an editor for "objects"

dm320:03:22

which have properties of various types

dm320:03:34

so you have different inputs generated dynamically

micha20:03:47

yeah that's where we factor things out

micha20:03:06

i've found that having too abstract an api is actually not helping

micha20:03:16

it's a tricky balance

micha20:03:37

but i try to make code that supports the developer at the page level

micha20:03:43

using macros sometimes, things like that

micha20:03:00

to allow the page to be assembled from less abstract parts

micha20:03:04

if that makes sense

micha20:03:20

like loop-tpl itself is an example of this kind of approach

dm320:03:31

agree completely

micha20:03:39

the things you put inside the loop-tpl can be very specific

micha20:03:48

they don't need to implement a protocol or anything

micha20:03:00

or have any abstract meaning in terms of loop-tpl stuff

micha20:03:06

i guess what i look for is a layer that is very vaguely specified

micha20:03:42

that's not a good way to put it

micha20:03:00

like the orgmode thing we made

micha20:03:19

that's a tree that is editable by the user

micha20:03:29

so you don't know in advance what the shape of it will be

micha20:03:43

a good example of what appears to be impossible to do with loop-tpl

micha20:03:07

but what i ended up doing was making a node function that generates a node of the tree

micha20:03:19

and it uses loop-tpl internally for its children

micha20:03:25

popupating that with more nodes

micha20:03:55

the actual DOM elements could depend on the data for that node

micha20:03:37

but we got excellent performance with large trees

micha20:03:46

hundreds of nodes on the page

micha20:03:58

without doing anything special

dm320:03:00

hm, how would you make node produce a different DOM element depending on the data?

dm320:03:25

(recall looking at the project, awesome! the amount of code you wrote and the abstractions)

micha20:03:56

the cond-tpl macro that's going to be merged seems like it would be ideal for that use case

micha20:03:14

usually i will start with :toggle, just hiding the elements that don't apply

micha20:03:50

if there is no need to do anything else then i'll just leave it like that, it seems simplest to me that way

micha20:03:01

i don't mind seeing hidden things in the dom inspector

micha20:03:28

so i think either of those would be a good thing to try at first

micha20:03:51

this type of problem is the hardest one you will face i think

micha20:03:10

and i don't think anyone has figured out a cookie-cutter solution to it

micha20:03:37

so you need to apply some tricks to get the result you want

micha20:03:09

it's the same in all kinds of computer programs really

micha20:03:28

dynamic allocation of trees is always going to be tricky

micha20:03:05

the usual way to attack it is to try to transform the problem into a linearization problem

micha20:03:15

like transform the tree into a sequence somehow

micha20:03:45

in clojure you have lazy seqs, and in hoplon you have those plus loop-tpl for the dom

micha20:03:35

in my experinece i've found that if i can express the problem in a way that can be approached with loop-tpl then everything will fall into place

micha20:03:41

and no performance issues will arise

dm320:03:31

appreciate your answers and time, @micha!

micha20:03:41

sure anytime

dm320:03:23

I was mainly thinking about the "Hoplon" way of conditionally rendering DOM elements. It's clear now. I'd think it's a common issue for people coming from React where the idiom is to (if a (component-x) (component-y))

micha20:03:01

yeah that's problematic in hoplon because a and b might be arbitrarily complex things

dm320:03:02

and Hoplon will have cond-tpl or switch-tpl

micha20:03:11

i mean x and y

micha20:03:24

or :toggle