karax icon indicating copy to clipboard operation
karax copied to clipboard

Question: Need clarification on behaviour of newComponent()

Open TheSimpleZ opened this issue 4 years ago • 2 comments

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

TheSimpleZ avatar Mar 09 '20 17:03 TheSimpleZ

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?

TheSimpleZ avatar Mar 09 '20 18:03 TheSimpleZ

AFAIK components have been completely broken for some time now, anyway.

dawkot avatar Apr 09 '20 20:04 dawkot