2

I am trying some beginner tutorials to understand data binding with Dart-Polymer, but none of the examples are working. I am able to run the samples included in the project, so wonder what's wrong with my code. From the following link, here is my code :

<!DOCTYPE html>

<html>
<head>
<script src="packages/web_components/dart_support.js"></script>
<!-- <script src="packages/web_components/platform.js"></script>
     not necessary anymore with Polymer >= 0.14.0 -->

<script async src="packages/browser/dart.js"></script>
<script async type="application/dart" src="bind.dart"></script>
</head>

  <body>
   <p>x = {{ x }}</p>

     <ul>
       <template iterate='item in list'>
         <li>list item = {{item}}</li>
       </template>
     </ul>

     <ul>
       <template iterate='key in map.keys'>
         <li>map key = {{key}}, map value = {{map[key]}}</li>
       </template>
     </ul>

  </body>
</html>

Dart file :

import 'dart:async';
import 'package:polymer/polymer.dart';

List list = toObservable(new List());
Map<String, num> map = toObservable(new Map());
@observable num x = 0;

void main() {

  initPolymer().run(() {
      Polymer.onReady.then((_) {

         new Timer.periodic(new Duration(seconds: 1), (_) {
         x += 1;
         list.add(x);
         map[x.toString()] = x;
         if (x % 4 == 0) {
         list.clear();
         map.clear();
         }    
          return x;
        });
     });
  });
}

When I run the above code, x = {{ x }} is printed with the following in console :

Top-level fields can no longer be observable. Observable fields should be put in an observable objects.

I tried dropping @observable from the variable "x" (and also dropped the reference in .html file), then nothing is printed. Here is revised HTML :

<!DOCTYPE html>

<html>
<head>
<script src="packages/web_components/dart_support.js"></script>
<!-- <script src="packages/web_components/platform.js"></script>
     not necessary anymore with Polymer >= 0.14.0 -->

<script async src="packages/browser/dart.js"></script>
<script async type="application/dart" src="bind.dart"></script>
</head>
  <body>
     <ul>
       <template iterate='item in list'>
         <li>list item = {{item}}</li>
       </template>
     </ul>
     <ul>
       <template iterate='key in map.keys'>
         <li>map key = {{key}}, map value = {{map[key]}}</li>
       </template>
     </ul>
  </body>
</html>

Revised DART file :

import 'dart:async';
import 'package:polymer/polymer.dart';

List list = toObservable(new List());
Map<String, num> map = toObservable(new Map());
num x = 0;

void main() {

  initPolymer().run(() {
      Polymer.onReady.then((_) {
         new Timer.periodic(new Duration(seconds: 1), (_) {
         x += 1;
         list.add(x);
         map[x.toString()] = x;
         if (x % 4 == 0) {
         list.clear();
         map.clear();
         }    
          return x;
        });
     });
  });
}
Community
  • 1
  • 1
dev
  • 11,071
  • 22
  • 74
  • 122

1 Answers1

1

There are two things:

<template id="bindValueTemplate" is="auto-binding-dart">
  <core-input id="bindValue" placeholder="bindValue" value="{{stringValue}}"></core-input>
</template>
  • You can not make a top level variable observable (as the error message says). The variable has to be in a class that extends or implements Observable:
class MyModel extends Object with Observable {
  @observable
  String stringValue;

  @observable
  bool isInvalid;

  Function changeHandler;
  Function inputHandler;
  Function inputInvalidHandler;
  Function inputValidHandler;
}

void main() {

  initPolymer().run(() {
    return Polymer.onReady.then((_) {
      var template =
          dom.document.querySelector("#bindValueTemplate") as AutoBindingElement;
          var model = template.model = new MyModel();
    });
}
Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
  • Thanks! Even after I drop the @Observable option (please see the last 2 code blocks I added in the question), and use access data from within template tags, it still does not work. I am unable to follow the second solution you offered, because my current dart module (which I have posted above) is not using any custom classes - and I would like to do it without creating a new polymer element class. – dev Aug 26 '14 at 04:33
  • My answer is only one solution that consists of two parts. You can't use @observable outside a class as the error message tells. – Günter Zöchbauer Aug 26 '14 at 04:35
  • Thanks again, I got it working :) Still trying to understand AutoBinding properly - seems useful. – dev Aug 26 '14 at 05:21
  • 1
    I used it only for the tests I linked to. Normally I use an `` Polymer element as a container for my entire app. I don't see a reason not to use AutoBindingElement though, but not so long ago AutoBindingElement was not yet available and binding was only supported inside an element and I stuck with this approach. – Günter Zöchbauer Aug 26 '14 at 05:24