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

No select example? #711

Closed
antony opened this issue Jul 12, 2017 · 9 comments
Closed

No select example? #711

antony opened this issue Jul 12, 2017 · 9 comments

Comments

@antony
Copy link
Member

antony commented Jul 12, 2017

I have a select box in my component which binds a value using two-way bindings.

<select bind:value='duration'>
        {{ #each durations as dur }}
          <option value="{{ dur }}">{{ dur }} months</option>
        {{ /each }}
      </select>

The component is nested inside a modal component which can show and hide.

It seems that when I hide and re-show the modal, whilst the 'duration' value has been persisted, the select has reset to the initial list item.

It seems like the two-way binding doesn't bind the selected value correctly.

It also appears that there is no <select> example available in the REPL.

Is there another binding I require, or is this an issue?

@Rich-Harris
Copy link
Member

Yeah, you're right — no example in the REPL, which is ironic since you select examples with a two-way bound select element!

Sounds like you've found a bug — are you able to reproduce it in the REPL? Thanks

@antony
Copy link
Member Author

antony commented Jul 12, 2017

Managed to reproduce the issue:

https://svelte.technology/repl?version=1.25.0&gist=d67ed619d2c308b9a20518fa694d64ac

note that after toggling, the duration is still correctly rendered, but the select is defaulted.

@stalkerg
Copy link
Contributor

I have the same code in my project but without IF statement in the nested component and all work fine. I think IF break all again.

@antony
Copy link
Member Author

antony commented Jul 13, 2017

Yeah, the if removes and reinserts things from the DOM.

The dropdown defaults to its original settings because the selected attribute on the currently selected option is not persisted (or set) by the value binding of its parent select, thus on re-render, the selected option defaults to its original setting.

@antony
Copy link
Member Author

antony commented Jul 19, 2017

If anybody else runs into this, I've managed a pretty ugly workaround using event firing. I struggled for a while as it's a dealbreaker for our use case (I'm dealing with loan calculations, so I definitely can't have incorrect calculations showing.), but I eventually resorted to this, which does work until this issue is resolved:

This resets my value to its original state, which in turn updates the calculated data to the correct values.

    oncreate () {
      this.refs.modal.on('show', e => {
        // https://github.com/sveltejs/svelte/issues/711
        this.refs.otherComponent.set({ myValue: 12 })
      })
    }

in my modal component, the show method now looks like this, so that an event is fired before the user sees the calculation:

methods: {
      show: function () {
        this.fire('show')
        this.set({ shown: true })
      }
}

Rich-Harris added a commit that referenced this issue Jul 25, 2017
Rich-Harris added a commit that referenced this issue Jul 25, 2017
ensure data is up to date when re-rendering yield blocks
@Rich-Harris
Copy link
Member

Thanks! This is fixed in 1.26

@antony
Copy link
Member Author

antony commented Jul 25, 2017

Aweeeesome! Now I can strip out all the ugly code from my widget :D

@stalkerg
Copy link
Contributor

Your fix broken binding in a cycle.
https://svelte.technology/repl?version=1.26.0&gist=b19f3eb28f65c23f505e00310b8dbc1b

I think you should reopen this bug.

@stalkerg
Copy link
Contributor

Fast fix:

diff --git a/src/generators/dom/visitors/Element/Binding.ts b/src/generators/dom/visitors/Element/Binding.ts
index b3c72fd..945145c 100644
--- a/src/generators/dom/visitors/Element/Binding.ts
+++ b/src/generators/dom/visitors/Element/Binding.ts
@@ -87,8 +87,16 @@ export default function visitBinding(
                const { name } = getObject(attribute.value);
                const tailSnippet = getTailSnippet(attribute.value);

-               updateElement = deindent`
-                       var ${value} = #component.get( '${name}' )${tailSnippet};
+               if (state.inEachBlock === true) {
+                       updateElement = deindent`
+                               var ${value} = ${snippet};
+                       `;
+               } else {
+                       updateElement = deindent`
+                               var ${value} = #component.get( '${name}' )${tailSnippet};
+                       `;
+               }
+               updateElement += `
                        for ( var #i = 0; #i < ${state.parentNode}.options.length; #i += 1 ) {
                                var ${option} = ${state.parentNode}.options[#i];

This was referenced Jul 26, 2017
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

3 participants