dashborg / hibiki

Hibiki HTML
https://www.hibikihtml.com/
Mozilla Public License 2.0
468 stars 6 forks source link

Should bind work on already binded parameters? #12

Closed tenuki closed 2 years ago

tenuki commented 2 years ago

Maybe there is a problem with the second binding in the case it is a 2-way bind or I am missing something..

The short-example is:

<template hibiki>
<hibiki-data>{"x": {"content": "something", "ready": false} }</hibiki-data>  
<define-component name="editpub">
<span>this is ok: {{$.x.content}}  /  ready: {{$.x.ready}} </span><br/>
<span>this is ok: {{$args.pub.content}}  /  ready: {{$args.pub.ready}} </span>
<div class="control">
  <label>1</label>
  <input class="input" type="text" value.bindpath="$args.pub.content"></div>
<div class="control">
  <label>2</label>
  <input class="input" type="text" value.bindpath="$.x.content">
</div>
<div class="control">
  <label>3</label>
  <input bound change.handler="$args.pub.ready=@value;"
             checked="* $args.pub.ready"
             type="checkbox">
</div>
</define-component>
<local-editpub pub.bindpath="$.x"></local-editpub>  
</template>

I would expect that input 1 works the same way as input 2, as I would like to do component dependent on its arguments rather than in global state.. I don't know what is happening here..

tenuki commented 2 years ago

Also this works fine (yes, in reality, my case is with textareas instead of input):

<textarea class="textarea" placeholder="Textarea" 
     value="*$args.pub.content" 
     change.handler="$args.pub.content=@value;">
</textarea>
sawka commented 2 years ago

Short answer: in your define component you want to set value and not value.bindpath:

<input class="input" type="text" value="*$args.pub.content"></div>

Long answer: underneath the hood when you write value.bindpath Hibiki converts the path into a "reference". The input control is smart and if it sees a reference as its value it will do 2-way binding. So value.bindpath="$.x" is the same as value="*ref($.x)" (just a nicer syntax with the bindpath). So since you've set the argument on your component to a reference already, you just pass it directly.

Normally the references will "just work" when you pass them into components. If you need to know whether something is a reference or not, you can use the isref($args.pub) function or refinfo($args.pub) to see what the reference is pointing at.

Happy to explain more in discord. I don't cover it much in the tutorial and docs, but Hibiki has really good support for components that are wrappers around things like inputs or textareas. With "automerge" you can make the new component function transparently as the wrapped component.

tenuki commented 2 years ago

Thank you for the (also quick) answer!

About discord, I've tried it but as I registered with my own domain, discord believed that I was a cheater or spammer or something and, no mater I used my country and my phone, etc, etc, banned me. :-(