karax
karax copied to clipboard
Question: Need clarification on behaviour of newComponent()
Hello!
I'm trying to create a component that wraps xterm.js. To initialize the terminal I need to call a few JS functions after a div has been attached to the DOM.
I was under the impression that the onAttach
parameter of newComponent()
was meant for this purpose, but I think i'm wrong. As seen here, the onAttachImpl
proc is called before renderImpl
:
https://github.com/pragmagic/karax/blob/db4acbf7d64549196b58928bb51c15252482f91c/karax/karax.nim#L162-L165
I believe this causes the onAttach
to be fired before the element actually exists. Is this on purpose? If yes, is there any way of knowing when an element has been fully loaded into the DOM?
Essentially, this is the code i'm using:
include karax / [prelude, vstyles, kdom]
import jsffi
import sugar
var Terminal {.importjs: "new Terminal()", nodecl.}: JsObject
type termi = ref object of VComponent
proc render(x: VComponent): VNode =
echo "rendered"
result = buildHtml:
tdiv(id = "terminal"):
text "hello"
proc loaded(x: VComponent) =
# This doesn't work because "terminal" doesn't exist yet
let thediv = getElementById(kstring"terminal")
# Initialize xterm.js
let term = Terminal
term.open(thediv) # This fails because thediv doesn't exist
term.write(r"Hello from \x1B[1;3;31mxterm.js\x1B[0m $ ")
echo "loaded"
proc createDom(): VNode =
result = buildHtml(tdiv):
newComponent(termi, render, loaded)
setRenderer createDom
Actually, nevermind. I figured out that I'm looking in the wrong place. setRenderer
has a parameter called clientPostRenderCallback
that is used for this purpose.
Edit: Actually, no. That only works for the root component since that's the only with with a setRenderer
. Is it possible to get similar behavior on a component level or do i have to expose an init()
proc from each component that i can call in the setRenderer
callback?
AFAIK components have been completely broken for some time now, anyway.