Карты в Списках в Картах

После долгих проб и ошибок я не могу понять, что делать со встроенными списками и картами в Dart, а также, как к ним можно обращаться через привязку данных Polymer. Цель состоит в том, чтобы прочитать файл JSON и создать таблицу HTML, которую можно фильтровать и сортировать. (Я просто жестко закодировал данные карты ниже для ясности.)

Я могу построить HTML-таблицу в своем элементе Polymer (см. BuildTable), если карта выглядит как testMap3, представленный в коде Dart ниже, и хорошо отрисовывается с помощью:

HTML:

<p><b>The data from testMap3 after building table in Dart file:</b>/p> 
<table class="bordered" id="dataTable"></table>     

Тем не менее, я не могу понять, как сделать это с помощью привязки данных Polymer. Сейчас я просто сбрасываю пары kv, чтобы увидеть объекты:

HTML:

<p><b>The data from testMap3 via Polymer binding:</b></p> 
<template repeat="{{key in testMap.keys}}">
  <p>{{key}} : {{testMap[key]}}</p>   
</template>

Как я могу использовать привязку данных для создания таблицы, которая будет соответствовать результату первого примера выше? И чтобы сделать вещи более сложными, как я могу сделать это, используя testMap2 вместо этого?

Dart:

Рендеринг testMap3 работает нормально при вызове buildTable:

Map testMap3 = toObservable({
                'columns' : ["First Name", "Attending", "Phone"],
                'rows' : [{'First Name' : "Alice", 
                           'Attending' : "Yes",
                           'Phone' : "555-1212"},                              
                          {'First Name' : "Bob", 
                           'Attending' : "Yes",
                           'Phone' : "555-2323"}                              
                         ]
           });

Итерация по testMap2 была проблематичной, учитывая, что дополнительное встроенное значение "Телефон" представляет собой список, содержащий другую карту:

 Map testMap2 = toObservable({
               'columns' : ["First Name", "Attending", "Phone"],
               'rows' : [{'First Name' : "Alice", 
                          'Attending' : "Yes",
                          'Phone' : [{'Home' : "555-1234",
                                      'Work' : "555-4321",
                                      'Mobile' : "555-1212"}]},                              
                         {'First Name' : "Bob", 
                          'Attending' : "Yes",
                          'Phone' : [{'Home' : "555-2345",
                                      'Work' : "555-5432",
                                      'Mobile' : "555-2323"}]}                            
                        ]
          });

Следующий код прекрасно работает для testMap3, но все, что я пробовал, позволяет мне просматривать данные телефона, если я использую testMap2. Любые идеи о том, как я могу это сделать?

buildTable() {

  TableElement table = this.shadowRoot.querySelector("#dataTable");
  table.children.clear();

  TableSectionElement tBody = table.createTBody();

  TableSectionElement tHead = table.createTHead();
  TableRowElement trh = tHead.addRow();

  for (var column in testMap3["columns"]) {
    var cell = new Element.tag('th');
    cell.text = column;
    trh.append(cell);
  }

  for (var row in testMap3["rows"]) {

    TableRowElement tr = tBody.addRow();
    for (var column in testMap3["columns"]) {
      tr.addCell().text = row[column];       
    }
  }   
}

Наконец, одна из конечных целей состоит в том, чтобы отфильтровать все столбцы в отображаемой таблице, используя подход, подобный следующему... это выполнимо? Я не могу найти примеры использования Карт или даже списков в списках.

HTML:

<template repeat="{{city in listOfCities | filter(searchParameter)}}">
  <li>{{city}}</li>
</template>

Dart:

@observable List listOfCities = ["Chicago", "New York", "Los Angeles", "Dallas", "Denver"];

filter(term) => (listOfCities) => term.isEmpty ? listOfCities : listOfCities.where((item) => item.toLowerCase().contains(searchParameter.toLowerCase())).toList();

Любое руководство очень ценится, так как я бился головой более недели и почти готов сдаться.

Спасибо!

2 ответа

Решение

Следующая привязка данных Polymer будет работать для testMap3:

<table>
  <thead>
    <tr>
      <td template repeat="{{column in testMap3['columns']}}">{{column}}</td>
    </tr>
  </thead>
  <tbody>
    <tr template repeat="{{row in testMap3['rows']}}">
      <td template repeat="{{data in row.keys}}">{{row[data]}}</td>
    </tr>
  </tbody>
</table>

Фильтрация по строкам таблицы может быть выполнена с помощью следующего метода:

filter(term) => (rows) => term.isEmpty
      ? rows
      : rows.where((row) => row.values.any((val) => val.toLowerCase().contains(term)));

Он просматривает все данные строки и сопоставляет каждый столбец с поисковым термином.

Тогда тело будет выглядеть так:

<tbody>
  <tr template repeat="{{row in testMap3['rows'] | filter(search)}}">
    <td template repeat="{{data in row.keys}}">{{row[data]}}</td>
  </tr>
</tbody>

И это предполагает, что у вас есть ввод текста, который подключается к строковому значению с именем search,

Вы можете попробовать это

<table>
  <thead>
    <tr>
      <th template repeat="{{item in testMap3['columns']}}">{{item}}</th>
    </tr>
  </thead>
  <tbody>
    <tr template repeat="{{row in testMap3['rows']}}">
      <td template repeat="{{key in testMap3['columns']}}">{{row[key]}}</td>
    </tr>
  </tbody>
</table>

<tr template repeat="...">

такой же как

<template repeat="...">

но вы не можете использовать