1
votes

I have the following core-elements dropdown element in which I used paper-item instead of core-item to display the dropdown label.

// .html

  <input required
    id='birthday'
    name='birthday'
    type='date'
    value="{{age.birthday}}"
    on-change='{{inputHandler}}'>

<div layout horizontal>
  <div layout vertical self-center
    id='years-div'>Years
    <core-dropdown  disabled
      id='years-core-ddwn'
      halign="left"
      label='0'
      valueattr="label">
      <template repeat="{{year in yearsList}}">
        <paper-item id='years-ppr-itm' label="{{year}}"></paper-item>
      </template>
    </core-dropdown>
  </div>

//.dart

var yearsList = <int>[ 1, 2, 3, 4]
@observable int year = 0;

class Age
{
  int years = 0;
  String birthday = '';     
} 


// calcualate age in years
      void inputHandler()
      {
        if ( age.birthday != '' )
        {
          DateTime now = new DateTime.now();
          DateTime birthday = DateTime.parse( age.birthday.replaceAll( r'-', '') );

          //Duration dayz = ( birthday.difference( new DateTime.now() ) ).inDays;
          Duration duration = new DateTime.now().difference( birthday );

          // calculate years since birth
          int days = duration.inDays;
          age.years = days ~/ 365;

      // attempting to set the PaperItem label to the calculated age
          yearsPprItm = $[ 'years-ppr-itm' ] as PaperItem;

          // neither of the following resets the PaperItem label to the age variable
          yearsPprItm.setAttribute( 'label', age.years.toString() );
          //year = age.years.toString();
    }  

The drop-down displays normally and selected item is retrieved normally also.
There are no error stack trace, yet the paper-item label is not changed using setAttribute or assigning the age.years to the observable year to which the label is bound.

I am wondering if it is illegal to bind to and iterator variable. If so, what is the correct method of accomplishing what I am trying to do.

Thanks

2

2 Answers

1
votes

You can't, as far as I know, expect the year

<template repeat="{{year in yearList}}">

to be a binding to

@observable int year;

As I think year in the template is a locally created variable, with nothing to do with the observable year you created in the backing class. I'd have to look up the documentation though, for a better explanation.

The only way to get the template to bind to year is to change

<template repeat="{{year in yearList}}">
    <paper-item label="{{year}}"></paper-item>
</template>

to

<template repeat="{{id in yearList}}">
    <paper-item label="{{year}}"></paper-item>
</template>

The problem with that is, when year is updated, it will update to the same value in each displayed. What I think you want is something like this

<template repeat="{{ year in yearList }}">
    <paper-item label="{{year.years}}"></paper-item>
</template>

with the backing yearList being

List<Age> yearList = [new Age(0), new Age(1), ...];

and Age being

class Age extends Observable {
    @observable int years;
    String birthday = '';

    Year(this.year);
}

Then you can update an item in the list and the change will be reflected in the display. At least that's something like what I think you're after. I'm sure there are other ways of doing this as well as what I suggest. Unless I'm also not understanding what it is you're after.

0
votes

edit

    <core-dropdown  disabled
                    id='years-core-ddwn'
                    halign="left"
                    label='0'
                    valueattr="label" selected="{{age.years}}"> <!-- added `selected` attribute -->
      <template repeat="{{year in yearsList}}">
        <paper-item label="{{year}}"></paper-item> <!-- don't add static id in <template repeat> -->
      </template>
    </core-dropdown>

make the Age class observable so the <core-dropdown> selection gets updated automatically.

class Age extends Observable {
  @observable
  int years = 0;
  String birthday = '';
}

old answer

This can't work:

  <template repeat="{{year in yearsList}}">
    <!-- for each item in yearsList a paper-item with the id 'years-ppr-itm' is created
         but 'id' is supposed to be unique. -->
    <paper-item id='years-ppr-itm' label="{{year}}"></paper-item>
  </template>

You just need to modify the yearsList list to contain the year values you want and the items update automatically.

What you need to change in your code to make it work:

change

var yearsList = <int>[ 1, 2, 3, 4];

to

var yearsList = toObservable(<int>[ 1, 2, 3, 4]);

toObservable() notifies Polymer about added/removed list items.
If you assign another list to yearsList instead of adding removing values you need to do it like

// declaration/initialization
@observable
var yearsList = toObservable(<int>[ 1, 2, 3, 4]);

...

// later assignment of a new list
yearsList = toObservable(<int>[ 5, 6, 7, 8]);

If you don't modify the list elements and always assign a new list to yearsList you can omit toObservable() but not @observable