dev
dev

Reputation: 11309

Template repeat not working for nested list (Polymer.dart)

Due to the lack of multi-dimensional array support in dart, I thought of using List.

Dart code :

class MyModel extends Object with Observable {
@observable
List<List<int>> dataList = toObservable(new List<List<int>>());
}

void main() {
  initPolymer().run(() {
    Polymer.onReady.then((_) {
      var template = querySelector("#bindValueTemplate") as AutoBindingElement;
      var model = template.model = new MyModel();

      for (int i=0; i<2;i++) {
        List<int> in1 = new List<int>();
        for (int j=0; j<2; j++) {
          in1.add(j);
        }
        model.dataList.add(in1);
      }

    });
  });
}

HTML file (snippet):

<body fullbleed touch-action="auto">
 <template id="bindValueTemplate" is="auto-binding-dart">
    <div id="dynamic_area" layout horizontal>
       <table template repeat="{{row in dataList}}">
           <tr template repeat="{{col in row}}">
              <td>{{col}}</td>
           </tr>
       </table>
    </div>
 </template>

</body>

Error I get in console:

Uncaught Error: Error evaluating expression 'row': Class 'MyModel' has no instance getter 'row'.
NoSuchMethodError: method not found: 'row'
Receiver: Instance of 'MyModel'
Arguments: []

When I added a 'row' list variable in MyModel with a getter, it throws the following error :

Uncaught Error: Unsupported operation: can't eval an 'in' expression

Upvotes: 2

Views: 1690

Answers (2)

G&#252;nter Z&#246;chbauer
G&#252;nter Z&#246;chbauer

Reputation: 657308

You assign the model to the template and only afterwards add the data.

I guess you need to make the inner lists observable too.

List<int> in1 = toObservable(new List<int>());

or a bit shorter

List<int> in1 = toObservable(<int>[]));

But the error message seems to point more to this issue http://dartbug.com/12742

Can you please try if it works inside a Polymer element instead of AutoBindingElement.

EDIT

Normally you don't add repeat on an element. Normally you use

<template repeat="{{x in y}}">
  <!-- repeate this y.length times -->
</template>

There are exceptions. For example <ul>, <tr>, and a few others,
because browsers do not allow HTML like

<table>
  <!-- this template element is just dropped by some browsers because 
       only some specific elements are allowed inside a `<table>` element. -->
  <template repeat="{{x in y}}">
    <tr>
    </tr>
  <!-- repeate this y.length times -->
</template>

As a workaround for such situations

<table>
  <tr repeat="{{x in y}}"> <!-- here not the children but the element itself is repeated -->
  </tr>
</table>

Upvotes: 2

dev
dev

Reputation: 11309

My understanding of template repeat was wrong. The repeat clause is to be applied for the the element itself, and not the children. This fixed the problem :

<body fullbleed touch-action="auto">
 <template id="bindValueTemplate" is="auto-binding-dart">
    <div id="dynamic_area" layout horizontal>
       <table>
           <tr template repeat="{{row in dataList}}">
              <td template repeat="{{col in row}}">{{col}}</td>
           </tr>
       </table>
    </div>
 </template>

</body>

And the updated dart code :

class MyModel extends Object with Observable {
@observable
List<List<int>> dataList = toObservable(new List<List<int>>());
@observable
List<int> row = [];      //I don't know why it works even without toObservable()
}

I am marking the question as resolved because my specific problem was resolved. But the question still remains what if we actually want to repeat table elements !

Upvotes: 3

Related Questions