Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

:model directive? #23

Closed
twuky opened this issue Jul 11, 2024 · 9 comments
Closed

:model directive? #23

twuky opened this issue Jul 11, 2024 · 9 comments

Comments

@twuky
Copy link
Collaborator

twuky commented Jul 11, 2024

Hello there - Just starting to try out and get familiar with this framework. If I'm to understand, binding the content of any kind of input to a variable that can be shared in other elements currently uses an event listener, like so:

<div :with="{ data: '' }">
    <input :value="data" :oninput="(e) => {data= e.target.value}">
    <button :onclick=" () => { doSomething(data)} ">submit</button>
</div>

I'm curious if it's feasible or within your goals to have a more vue-style v-model directive for input fields, where the above has a bit more sugary syntax:

<div :with="{ data: '' }">
    <input :model="data">
    <button :onclick=" () => { doSomething(data)} ">submit</button>
</div>

Am I correct there isn't a directive directly like this in sprae already? If something like the first example is best-practice for what it does, it may be useful to have it as an example in the readme as well.

edit: Ah, I've just run into https://github.com/dy/sprae/blob/main/r%26d.md#x-value-is-confusing--also-uses-that---lets-skip-for-now-onchange-is-not-a-big-deal
It does seem fairly plausible to implement with the custom directives, though. I may look into writing one

@dy
Copy link
Owner

dy commented Jul 11, 2024

Yes, I see reasoning in r&d why :model was rejected:

<input :value="value" :onchange="e=>value=e.target.value" />
  + more apparent and explicit
  + less mental load, "model" is too heavy term
  + overhead is minimal
  + react-like
  + it has better control over serialization - what exactly value is being written
  + `:onchange:oninput="e=>value=e.target.value"` is handy helper

But if you prefer to have :model as custom directive, you can propose a PR, I can include it as optional directive. The point of sprae was to be slim, so I tried to shave off things that can be expressed in alternative more basic ways.

@dy
Copy link
Owner

dy commented Jul 11, 2024

I wonder if my logic was incomplete, eg.

  • :value is not directly value attribute as one might expect, but normalized setter.
  • are there cases when we need to set value, but not read it? readonly inputs are rare and also covered by :model
  • it's trivial to bind event listeners properly by framework, also saves client code

I may consider replacing :value with :model indeed

@twuky
Copy link
Collaborator Author

twuky commented Jul 11, 2024

looking at the code for :value - I definitely agree that duplicating ~half of it's logic into a seperate directive does seem like a waste.

If value were changed to reflect the behavior of :model - maybe use modifiers to signify read/write behavior:

:value="my_model"
:value.r="readonly"
:value.w="writeonly"
:value.rw="my_model" // same as default

Rather, if writeonly was by default - then you could update the library in-place and it would be a nonbreaking change.
In terms of bundle size, I think being able to simplify this syntax in the HTML would outweigh the added code size fairly quickly.

@dy
Copy link
Owner

dy commented Jul 11, 2024

Yes, I also had that in mind, binding value both ways. Either do it right away via :value or via :value.bind. The only question if user ever needs one-way value setter, so that changing input value doesn't affect state.
From practice I never saw it, so most likely :value for both ways is fine.

@twuky
Copy link
Collaborator Author

twuky commented Jul 11, 2024

I can't personally think of a case where id use a read-only :value - it seems like a :text or :html on any other kind of element would be more ideal for a case like that.

I think :value.bind would also be fine ergonomics, if you are worried about existing pages getting undefined behavior. Either way seems okay to me.

@dy dy mentioned this issue Jul 12, 2024
@dy
Copy link
Owner

dy commented Jul 12, 2024

@twuky added in #25 - I've invited you as collaborator if you want to review the PR / suggest changes

@dy
Copy link
Owner

dy commented Jul 12, 2024

Ok, I just merged it, so must be fixed.

@dy dy closed this as completed Jul 12, 2024
@twuky
Copy link
Collaborator Author

twuky commented Jul 12, 2024

I took a look at the branch last night but haven't had the chance to pull it into any projects yet. I'll let you know if anything breaks

@twuky
Copy link
Collaborator Author

twuky commented Jul 22, 2024

just checking in on this: value works totally as expected for me so far - was able to clean up a lot with it :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants