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

Svelte / Vue style two-way bindings. #4

Open
rebo opened this issue Feb 1, 2020 · 3 comments
Open

Svelte / Vue style two-way bindings. #4

rebo opened this issue Feb 1, 2020 · 3 comments

Comments

@rebo
Copy link
Owner

rebo commented Feb 1, 2020

Svelte and some other frameworks use two way bindings to reduce boilerplate. Here is an example from Svelte's website:

<script>
	let a = 1;
	let b = 2;
</script>

<input type="number" bind:value={a}>
<input type="number" bind:value={b}>

<p>{a} + {b} = {a + b}</p>

We can mimic this in seed as per the below. Admittedly, it's not quite as concise but it does the job.

fn numberbind() -> Node<Msg> {
    let a = use_istate(|| 0);
    let b = use_istate(|| 0);

    div![
        input![attrs![At::Type=>"number"], bind(At::Value, a)],
        input![attrs![At::Type=>"number"], bind(At::Value, b)],
        p![format!("{} + {} = {}", a.get(), b.get(), a.get() + b.get())]
    ]
}

Is this something we want to see?

@MartinKavik
Copy link
Contributor

On the first look:
Advantages

  • Reduced boilerplate.
  • I don't need to think about events and callbacks.

Disadvantages / Questions

  • Implicit - I don't know which event handlers are registered, I don't see any get, set or update values, I don't know that it fires messages.
  • It's separated from other attrs.
  • What happens when you use it with native elements which doesn't support set/get_value - runtime error?
  • How it works with custom elements?
  • Does it work the same for Copy, Clone and non-clonable state variables?
  • Does it automatically convert values to state variable types? (I see intergers in your example)
  • It makes a sense to pair bind with use_state but it would be an anti-pattern for most view functions because you cannot choose appropriate Msg to fire. It can lead to less consistent code.
  • Another thing to learn.

@rebo
Copy link
Owner Author

rebo commented Feb 4, 2020

Implicit - I don't know which event handlers are registered, I don't see any get, set or update values, I don't know that it fires messages.

Currently it just registers Ev::Input and sets the appropriate attr! listed (i.e. normally At::Value). It updates the use_state accessor via .set() on the Ev::Input change argument. Only currently works if there is a Default NoOp, so compiler will at least complain if Msg has no default.

It's separated from other attrs.

Yes so if At::Value was set independently there would be a clash not sure who seed decides which one wins. Maybe the last applied?

How it works with custom elements?

Currently would only work if custom element fired the Ev::Input event, however could allow for custom events via say custom_bind(Ev::CustomInput, At::Value, val)

Does it work the same for Copy, Clone and non-clonable state variables?

Yes.

Does it automatically convert values to state variable types? (I see integers in your example)

Currently yes only updates state variable if parse suceeds. However probably need to 'revert' the At::Value if parse fails to keep both UI and state in sync.

but it would be an anti-pattern for most view functions because you cannot choose appropriate Msg to fire

True however this would only be for inputs which you dont want reaching your business logic. For instance maybe a number of individual inputs could be used to configure a "Search" struct. This would reach the app via a normal message SearchFor(SearchObject) on submit button which is a bit more purposeful maybe. As opposed to SearchCategoryChanged , SearchRadioButtonSelected, SearchRegularityChanged, SearchMostRecentTrueChanged messages which all need to be handled individually.

@MartinKavik
Copy link
Contributor

My opinion - it looks interesting but also complex. And I think we don't have to modify Seed to use it (once Seed supports at least use_state) - so I suggest to implement it in a standalone library (with other helpers and hooks).

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