PolymerElements / iron-selector

Manages a list of elements that can be selected
32 stars 55 forks source link

Multi input does not seem to update host property #103

Open kjlubick opened 8 years ago

kjlubick commented 8 years ago

http://jsbin.com/yaquqovaca/4/edit?html,output

Expected behavior: Clicking on gamma will update the text field to show alpha,beta,gamma Clicking on beta will further update the text field to show alpha,gamma

Observed behavior: Clicking on gamma properly selects gamma, but does not update text field. Clicking on beta properly deselects beta, but does not update text field.

brycehill commented 8 years ago

I am seeing something similar when using the iron-multi-selectable.html behavior. From what I could track down, changes (push or splice) to selectedValues are not notifying properly and thus are not calling the _updateSelected observer.

fooloomanzoo commented 8 years ago

If I understand your problem correctly, I think your problem is, that the property selectedValues is an Array and therefore you should access its content by a dom-repeat template

    <template is="dom-repeat" items="{{exclude}}">
      <span>{{item}}</span>
    </template>

And so there is not a problem

http://jsbin.com/jicineroku/edit?html,output

kjlubick commented 8 years ago

fooloomanzii, thanks for the demo. However, I do not wish to use the output in a dom-repeat. I am using those values to filter other data, and so using selectedValues in a dom-repeat is not a solution for me.

fooloomanzoo commented 8 years ago

It might not be so well documented in the APIs, but you need to read how observation on Arrays work in Polymer for that. https://www.polymer-project.org/1.0/docs/devguide/data-binding.html There are some specific parts about it. If you just want to watch what changed in an Array, you just can set an observer-function:

    observers:
      ["watchExclude(exclude.*)"],

    watchExclude: function(changerecord) {
      console.log("changerecord:")
      console.log(changerecord);
      console.log("exclude: " + this.exclude);
    },

    filter: function() {
      var pos = this.exclude.indexOf('gamma');
      return this.exclude[pos];
    }

If you want to propagate received changes to the template, then it is simmular:

<span>{{filter(exclude.*)}}</span>

The part " .* " means, that you watch all subproperties. The observer-function gets an argument, what descibes all mutation operations happened on the Array, but you also can just access the original Array. I would also look into the code of iron-selector, because you could also adopt some ideas to reduce the code for what you want, so that your code is more efficient. The Array functions are usually set, push, splice, pop or shift, that is implemented to your element, like:

this.pop("excludes");

so that changes can be notified allover the DOM. But they really don't seam to work for selectedValues, allthough the changes are notified within the element:

http://jsbin.com/yewabigihe/1/edit?html,console,output

kjlubick commented 8 years ago

Thank you for the detailed reply fooloomanzii, that's enough for a workaround.

lbustelo commented 8 years ago

@fooloomanzii That solution works fine when you are in your own dom-module but does not work in a dom-bind template. The following does not work as expected

<template is="dom-bind">
    <paper-menu attr-for-selected="label" multi selected-values="{{selections}}">
        <paper-item label="1">Network 1</paper-item>
        <paper-item label="2">Network 2</paper-item>
        <paper-item label="3">Network 3</paper-item>
    </paper-menu>
    <h1>{{selections}}</h1>
    <template is="dom-repeat" items="[[selections]]">
        <span>[[item]]</span>
    </template>
</template>

The h1 is only updated once, when the first selection is made. I would expect to not have to write extra watcher code to have this work.