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.)
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 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:
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:
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.
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:
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.
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:
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.
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.
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.)
(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 teamI 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
- Join the web-ui@ and polymer-dev@ mailing lists.
- File bugs on polymer.dart at dartbug.com/new.
- Read all about Polymer.
- Have fun! :)
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.