Skip to content

How to migrate inline HB-helpers #9

Open

Description

@evil-shrike

I have a HB helper, let's call data-bind. It's being used as:

<input {{data-bind name="value" prop="myprop"}}>

it creates two-way data-binding between an DOM-element and an object. During template execution it return html string. Like " id='x1' ". So the above code become <input id='x1'>. It allows later after template executed and its html inserted into DOM find the element and initialize binding.
I understand that with incremeanl-dom two-way binding can be unneeded. But it's just an example of such a helper.
So I'm trying to understand what helper should return in case of ibars backend.
At first attempt I just tried to call: IncrementalDOM.attr("id", <generated_id>); in my helper. But it does nothing.
In debugger I can see generated template 's code as:

IncrementalDOM.elementOpen("div", "idom-430", null, ""
    + (helpers['data-bind'] || (depth0 && HBX.get(depth0, 'data-bind')) || helpers.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"data-bind","hash":{"prop":"myprop","name":"value",},"data":data})
    + "", ""))

So after my helper returned then IncrementalDOM.elementOpen is called with "undefined" in its last argument. Like: IncrementalDOM.elementOpen("div", "idom-430", null, "undefined")
So ibars expects that helper returns a string for a single attr name. No more.
But the last argument of elementOpen according to the docs is a dynamic list like ...args - http://google.github.io/incremental-dom/#api/elementOpen
It seems logically to support returning an array and convert it into method's args.

Anyway what would be a possible workaround for such a case? What should helper return?

It's mentioned in READ that:

It is however totally possible to create an ad-hoc 'attribute' helper that does that directly on the DOM element. This is again something I never do as in my opionion returning html artifacts from templates smells of anti-pattern.

How such ad-hoc helper could be implemented?

Activity

  1. evil-shrike commented on Jun 1, 2018

    @evil-shrike
    Author

    Let me add one more example

    Givien a template:

    <input {{data-bind value="myprop" }} />
    

    Emitter returns:

    "(IncrementalDOM.elementVoid("input", "idom-4", null, ""{{data-bind value="myprop"}}"", ""))"
    

    After that Handlebars compiler processes and expand helpers into the following template function:

    (function anonymous(container,depth0,helpers,partials,data
    ) {
      return (IncrementalDOM.elementVoid("input", "idom-4", null, ""
        + (helpers['data-bind'] || (depth0 && HBX.get(depth0, 'data-bind')) || helpers.helperMissing).call(depth0 != null ? depth0 : (container.nullContext || {}),{"name":"data-bind","hash":{"value":"myprop"},"data":data})
        + "", ""));
    })
    

    What I was thinking about is that emiiter should not wrap a helper call into quotes. Instead it could construct an array like this:

    (IncrementalDOM.elementVoid.apply(null,["input", "idom-4", null].concat( {{data-bind value="myprop"}} || []) )
    

    then helper could return an array like ["id", "x1"] and it will be passed into elementVoid.
    At the end we'll get a call like IncrementalDOM.elementVoid.apply(null,["input", "idom-4", null, "id", "x1"]. So that helpers will be able to pass arbitrary attr and their values into idom.

  2. atomictag commented on Jun 1, 2018

    @atomictag
    Owner
  3. evil-shrike commented on Jun 1, 2018

    @evil-shrike
    Author

    Ok. Can I ask you how do you add event handlers for html elements? Handlebars itself doesn't have a notion of event handlers, helpers can't access dom nor vdom so they also can't add handlers. So what are options do you have? Just manually subscribe after patch?

  4. atomictag commented on Jun 1, 2018

    @atomictag
    Owner
  5. evil-shrike commented on Jun 1, 2018

    @evil-shrike
    Author

    Such a callback would be called for every element right? But how can I tell from my template that for a particular button I need a click handler? I'd need to store some meta info and current context on a element and then later in that onOpen callback find them and subscribe to appropriate event. But we don't have any access to element in helpers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions