In fact, it is maybe not even too far away:
    
    
    include karaxprelude
    import jstrutils, dom, future
    
    type
      Model = ref object
        toggle: bool
      
      EventHandler = (Event, VNode) -> void
      EventHandlerModel = (Model, Event, VNode) -> void
    
    
    proc curry(handler: EventHandlerModel, model: Model): EventHandler =
      result = (ev: Event, n: VNode) => handler(model, ev, n)
    
    proc onClick(model: Model, ev: Event, n: VNode) =
      kout(ev)
      kout(model)
      model.toggle = model.toggle xor true
    
    proc view(model: Model): VNode =
      result = buildHtml():
        tdiv:
          button(onclick=curry(onClick, model)):
            text "click me"
          tdiv:
            text "Toggle state:"
          tdiv:
            if model.toggle:
              text "true"
            else:
              text "false"
    
    proc runMain() =
      
      var model = Model(toggle: true)
      
      proc renderer(): VNode =
        # var model = Model(toggle: true)   # init here does not work
        view(model)
      
      setRenderer renderer
    
    runMain()
    

At first I was initializing the `model` in the renderer proc. This had the 
result that the view never updated -- it's not immediately clear to me why it 
has to be in the outer scope.

Adding an Elm-like message approach should also be possible by constructing 
some `Msg` in each event handler and calling an `update` function. Okay, in 
contrast to Elm the model is updated in-place, but maybe it is even beneficial 
to keep the model update close to how it works natively.

The only issue is that every event handler has to be curried. So my question 
probably becomes: Is it possible to automatize this "injection" of the model 
into the event handlers, so that an event handler `(Model, Event, VNode) -> 
void` can be passed directly to `on...`.

Reply via email to