How to capture item model.index of the dom-repeat template (or iron-list) on Dart side?

Issue

In the following example:

captureIndex.html

<template id="lista_produtos" is="dom-repeat" items="{{produtos}}" as="item">
   ...
   <paper-input label="Custo" value="{{item.aquisicao_custo}}"type="number" on-change="calcularPrecoSugeridoEvento"><div prefix>R$</div></paper-input>
   ...
</template>

captureIndex.dart

@property
List produtos = [
  {
    "produto": "Prego",
    "unidade": "Unitário",
    "margem_contribuicao": 10.0,
    "preco_sugerido": 5.0,
  },
  {
    "produto": "Madeira",
    "unidade": "Unitário",
    "margem_contribuicao": 10.0,
    "preco_sugerido": 5.0,
  }
];

@reflectable
void calcularPrecoSugeridoEvento(Event e, d) {
  DomRepeatModel model = new DomRepeatModel.fromEvent(e);

  // IT´S WORKS. DATA ARE SHOWN!!!!
  Map m = model.item; 
  window.alert(m.toString());

  // IT IS NOT WORKS. INDEX IS NOT SHOWN!!!!
  int i = model.index;
  window.alert(i.toString());
}

I would like to capture model.index. But it is null.

I would not like to use html tag with event, with normally it´s suggested:

...
<template id="lista_produtos" is="dom-repeat" items="{{produtos}}" as="item">
   <paper-input id={{index}} on-change="eventX></paper-input>
</template>
...

...
void event (e, d) {
   window.alert((e).attributes['id']));
}
...

Is there some form to capture the index through model?

Solution

id={{index}} is a bad idea.

  1. You shouldn’t bind to the id attribute.
  2. The id attribute must not start with a number. id="123" is invalid id="a123" or id="_123" would work but you still should not bind to the id attribute.

If you don’t want to use an HTML attribute you can use

@reflectable
  calcularPrecoSugeridoEvento(dom.Event event, [_]) {
  ($['lista_produtos'] as DomRepeat)
      .modelForElement(event.target).jsElement['index'];
}

If you do want to use an HTML attribute you need to add ‘$’ to the attribute name to actually bind to the attribute (reflected in the DOM) and not to a property (JS only):

<paper-input data-index={{index}} on-change="calcularPrecoSugeridoEvento></paper-input>

then you can access the index using

new PolymerEvent(event).localTarget.dataset['index']
// or
new PolymerEvent(event).localTarget.attributes['data-index']

For <template id="lista_produtos" is="dom-repeat" ...> I successfully used these two variants to get the DomRepeatModel

  @reflectable
  event([dom.Event event, _]) {
    DomRepeatModel model = ($['lista_produtos'] as DomRepeat)
        .modelForElement(event.target);
    // or
    model = 
        new DomRepeatModel.fromEvent(convertToJs(event));    
    var index = model.index;
  }

Answered By – Günter Zöchbauer

Answer Checked By – Candace Johnson (FlutterFixes Volunteer)

Leave a Reply

Your email address will not be published.