使用镜像生成动态表

时间:2014-05-18 12:11:52

标签: dart angular-dart

我一直在尝试使用ng-repeat生成一个html表,而不必知道数据的结构,所以我使用了如下结构

    //wraps rows and column defwntions   
    class ItemsCollection{
      List<ColumnDef> ColumnDefs;
      List<DynamicItem> Items;
      ItemsCollection(this.ColumnDefs,this.Items);
    }

    //represents a column 
    class ColumnDef{
      int id;
      String name,displayName,tableName;
      bool isPrimaryKey,isNumeric,isCalculated;
      ColumnDef({this.name,this.displayName,this.tableName,this.isPrimaryKey,this.isNumeric,this.isCalculated});
    }

    //represents a data row ,since i don't know how the structure of the data looks like before run time the following class adds properties dynamically if they are not defined
    class DynamicItem{
      Map<String,Object> properties;

      DynamicItem([Map<String,Object> initialProperties]){
          this.properties = initialProperties == null ? new Map<String,Object>() : initialProperties;
        }

      noSuchMethod(Invocation invocation){
        if(invocation.isAccessor){
          final realName = MirrorSystem.getName(invocation.memberName);
          if(invocation.isSetter){
            final name = realName.substring(0,realName.length - 1);
            properties[name] = invocation.positionalArguments.first;
            return null;
          } else {
            return properties[realName];
          }
        }
        return super.noSuchMethod(invocation);
      }
    }

//and a part of simple angular directive to render the table
@Component(
    selector: 'table-component',
    publishAs: 'ctrl',
    template: '''<button ng-click="ctrl.addClalculatedCoulmn()">Add Calculated Column</button>
                <table border=2px}">
                    <thead>
                       <tr>
                         <th ng-repeat="col in ctrl.ItemsSource.ColumnDefs">{{col.displayName}}</th>
                       <tr>
                    </thead>
                     <tbody>
                       <tr ng-repeat="item in ctrl.ItemsSource.Items">
                         <td ng-repeat="col in ctrl.ItemsSource.ColumnDefs">
                            {{item.properties[col.name]}}
                         </td>
                       </tr>
                    </tbody>
                 </table>'''
)
class TableComponent {
  ItemsCollection ItemsSource;

  TableComponent(){
      ItemsCollection = service.getItemsCollection();
  };

  void addCalculatedCoulmn(string MathmaticlExpression){
     //adds a new column to the defentions
     //adds a new property to each row
  }
}

这是完美但有点慢,我的主要目标是在运行时添加计算的coulmns +不必担心编写我的模型,我想建立一个网格控制,但我不确定这是不是最好的解决方案,我测试了超过20000个数据对象,有6个属性+ 2个计算的,并花了37秒,我不知道为什么它的速度慢,任何建议,使其更快或任何想法,以避免使用反射和保持动态吗?

我也在服务器端使用dart,我想确保我没有错过任何可以帮助我实现这些事情的概念,性能是最重要的,除了我不想要用手代表模型中的数据,我将不胜感激。

1 个答案:

答案 0 :(得分:2)

我最近在原型中做了类似的事情;最后只是在数据结构中包含字段名称等(它来自服务器作为JSON)。

我的数据看起来像这样:

class ClientGrid {
  List<ClientGridColumn> cols;
  List<List<Object>> data;
  int currentPage;
  int totalPages;
  int totalRecords;
  int recordsPerPage;
}

class ClientGridColumn {
  String name;
  bool visible;
}

这样的代码:

var table = new TableElement();
table.className = "table table-hover";

var headerRow = table.createTHead().addRow();
data.cols.forEach((c) {
  if (c.visible)
    headerRow.append(new Element.tag('th')..text = c.name);
});

var body = table.createTBody();

data.data.forEach((r) {
  var row = body.addRow();
  r.asMap().forEach((i, c) {
    var col = data.cols[i];
    if (!col.visible)
      return;

    var cellContents = new SpanElement()
          ..text = c.toString();

    row.addCell().children.add(cellContents);
  });
});

this.children.add(table);