Polymer Dart $[] selector in an autobinding model

2019-03-02 05:02发布

问题:

Since polymer-body has been removed, we need to use an auto-binded template to use polymer binding features outside of a PolymerElement:

<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Sample app</title>
    <script src="packages/web_components/platform.js"></script>
    <script src="packages/web_components/dart_support.js"></script>
    <link rel="import" href="packages/polymer/polymer.html">
    <script src="packages/browser/dart.js"></script>
  </head>
  <body>
      <template is="auto-binding-dart">
        <div>Say something: <input value="{{value}}"></div>
        <div>You said: {{value}}</div>
        <button id="mybutton" on-tap="{{buttonTap}}">Tap me!</button>
      </template>

      <script type="application/dart">
        import 'dart:html';
        import 'package:polymer/polymer.dart';
        import 'package:template_binding/template_binding.dart';

        main() {
          initPolymer().run(() {
            Polymer.onReady.then((_) {
              var template = document.querySelector('template');
              templateBind(template).model = new MyModel();
            });
          });
        }

        class MyModel extends Observable {
          //$['mybutton'] wont works there
          @observable String value = 'something';
          buttonTap() => print('tap!');
        }
      </script>
  </body>
</html>

Unfortunately, the whole model now extends Observable, every binding seems to work, but the PolymerElement array selector $['foo'] cant be used anymore...

Is there any easy way to implement this $['id'] selector into an Observable model?

回答1:

I would suggest to use a normal Polymer element instead of auto-binding-dart.
Then you don't have to care about differences and you need no 'main'. I always start a Polymer project with an <app-element> Polymer element that acts as main() and container for the entire app.

I also would suggest to not use inline code.
As far as I know it has some limitations especially debugging is not supported (might be fixed already, I don't know because I never use it).

To make $ work you need a small and simple workaround;

import 'dart:html';
import 'package:polymer/polymer.dart';
import 'package:template_binding/template_binding.dart';


Map<String, dynamic> $; // we define our own '$'

main() {
  initPolymer().run(() {
    Polymer.onReady.then((_) {
      var template = document.querySelector('template') as Polymer;
      $ = template.$;             // we assign template.$ to our own '$' so we can omit the 'template' part
      templateBind(template).model = new MyModel();
    });
  });
}

class MyModel extends Observable {
  //$['mybutton'] wont work there - it can't because this is outside of a method
  @observable String value = 'something';
  buttonTap() {
    print($['mybutton'].id); // here it works
    print('tap!');
  }
}