Polymer and Dart: A First Look

In which I try the new polymer.dart, a build.dart file is deleted, and a template springs to life.

(This post heavily inspired by Nik Graf's great "Getting started with Polymer.dart" post.)

The web is evolving


Developers take notice! Coming soon: actual encapsulation, real live data binding, even re-usable components! The Web Components family of specifications is on their way to a browser near you, but the standardizations process is lengthy. Fear not, web engineers are working hard to bring these new capabilities to you today.

The Polymer project, a new type of library for the web, is built on top of Web Components, and designed to leverage the evolving web platform on modern browsers. Most importantly, the Polymer project has code that you can use today (to be fair, it's pre-alpha, but much of it works if you are brave).

The Polymer project is more than just polyfills.

Web UI is evolving


The Dart project, to more closely align with emerging web specifications, is building polymer.dart, the next evolution of Web UI. In the announcement, it was mentioned that Web UI will be sunset in favor of polymer.dart. While Web UI will be around for some time, new work focuses on polymer.dart.

From the Polymer project FAQ:

How is polymer.dart related to Polymer?
polymer.dart is a Dart port of Polymer created and maintained by the Dart team. The Dart team is collaborating with the Polymer team to ensure that polymer.dart elements and polyfills are fully compatible with Polymer.

Luckily for developers, polymer.dart and Web UI are fairly similar. It shouldn't be too much work to port a Web UI app to polymer.dart. We anticipate docs and examples to help developers with the transition.

There are many good reasons for this evolution:

  • closer alignment to another team building out support for Web Components
  • eventual elimination of the build/compile step required by Web UI
  • better interop between JavaScript components and Dart components
  • Dart developers get faster access to critical polyfills like Web Animations and Pointer Events

There's no rush for you to upgrade. Polymer.dart is very new, and it will be some time before it is feature compatible with Web UI. So, stick with Web UI if you're building production apps and wait for the transition guides to appear.

Aside: What about Angular?


Many developers want to know what's up with Angular, and how it all relates. I can't speak for the Angular project, but this post to the Polymer mailing list from Miško Hevery should shed some light:

We're in early stages of designing Angular 2.0, but some of our goals are: 
- Angular will use the underlying web platform features available to it (e.g. Node.bind, template integration, Custom Elements, etc...) 
- Web Components (Polymer, Ember, or any other framework/library) will work seamlessly within Angular apps and directives. 
- Components written in Angular will export to Web Components (to be used by Polymer, Ember, or any other framework/library) . 
We're working actively with the MDV, Web Components, and Polymer teams to make sure that our approaches remain compatible as all these projects evolve (and they will still evolve). 
-- Misko & the Angular team
I look forward to frameworks like Angular using the foundation of Web Components.

Hello, Polymer.dart


Let's give polymer.dart a try! For this first look, we'll build a very simple "Hello, World" example that shows off how to install polymer.dart, use the <template> tag, and bind a model.

Installing the polymer package


Add the polymer pub package to your pubspec.yaml. For this simple example, this is the only package that you'll need to explicitly declare:

name: polymer_first_look
dependencies:
  polymer: any


Creating the template


Add a <template> element to the web/index.html file. A <template> is an inert DOM fragment. It's valid HTML, but not activated by the page. You can manually clone the element and insert the clone into the page. Or, even better, you can use Model-Driven Views (MDV) to bind data to the template. The binding of data to the template activates the template, thus inserting it into the page.

The bind attribute on the <template> element states that the template activates (is cloned and inserted into the DOM) when data is bound to the template. The bind attribute comes from MDV.

The {{ and }} mark data binding between a field and some text. The field comes from the model data objects bound to the template. The {{ and }} are removed and replaced with the value of the field.

<!DOCTYPE html>

<html>
  <head>
    <title>index</title>
  </head>
 
  <body>   
    <template id="tmpl" bind>
      <p>Hello {{msg}}</p>
    </template>
    
    <script type="application/dart" src="index.dart"></script>
    <script src="packages/browser/dart.js"></script>
  </body>
</html>


Binding the data


The application, in web/index.dart, creates a single model object (a plain Dart object) and then attaches it to the <template> element from the page.

We must import the MDV package and initialize it before binding can have any effect.


import 'dart:html';
import 'package:mdv/mdv.dart' as mdv;

class Message {
  String msg;
}

main() {
  mdv.initialize();
  
  var message = new Message()..msg = 'world';
  query('#tmpl').model = message;
}


One big difference between Web UI and Polymer.dart: you must explicitly bind your model to the template. Web UI worked with code generation and lexical scope. Polymer.dart, because it comes from a JavaScript-influenced Polymer project, does not have code generation or lexical scope.

And that's it! There's no need for a build.dart with this simple test app. This works in Dartium and via dart2js. (Note: dart2js + polymer.dart output size is quite large, but follow dartbug.com/11524 for a fix.)

Next steps


This is just the beginning, there's a lot to explore with polymer.dart. I'm looking forward to more experiments as I learn about this brave new world.

Popular posts from this blog

Lists and arrays in Dart

Converting Array to List in Scala

Null-aware operators in Dart