AngularDart
&
Polymer.dart

by a compiler engineer


__ cmpl(FieldAddress(field_reg,
                     Field::guarded_cid_offset()),
        Immediate(kDynamicCid));
__ j(EQUAL, &ok);

<cmpl> <FieldAddress>…</FieldAddress>,
       <Immediate>kDynamicCid</Immediate></cmpl>
<j cond="EQUAL" href="#ok"></j>

when we were kids

DHTML

XSLT

$HTML


          var $ul = $("<ul/>", {class: "nav nav-tabs"});

for (var i = 0; i < tabs.length; i++) {
  $("<li/>").append($("<a href='#'/>").text(tabs[i]))
            .appendTo($ul);
}

$ul.appendTo($menu);

item(title) =>
  new LIElement()..nodes.add(
      new AnchorElement(href: "#")
        ..text = title);

menu.nodes.add(
  new UListElement()
    ..classes.addAll(["nav", "nav-tabs"])
    ..nodes.addAll(tabs.map(item)));

hmm?

AngularDart

Model-View-Controller

Model-View-Whatever

View: DOM

M&C: Dart objects

V⇔M&C

is managed automatically

2 + 2 = {{2 + 2}}

2 + 2 = {{2 + 2}}

+ = {{v1 + v2}}

+ = {{V + V}}

Hello {{name | uppercase}}!

Name:

But is it extensible?

Yes!

uppercase
is a filter


@NgFilter(name: 'capitalize')
class Capitalize {
  call(val) {
    if (val is String) {
      return (val.length <= 1) ? val.toUpperCase() :
        val[0].toUpperCase() +
        val.substring(1).toLowerCase();
    }
    return val;
  }
}

// Tell Angular about the new filter we made.
ngBootstrap(new Module()
  ..type(Capitalize));

Hello {{name | capitalize}}!

Name:

ng-model
is a directive

directives

decorators

Hello {{name}}!

Hello {{name}}!

Name:

@NgDirective(
  selector: 'input[type=text][my-integer-validator]'
)
class MyIntegerValidator {
  // ...
}

var el;

MyIntegerValidator(dom.Element this.el) {
  el.onChange.listen((_) => validate());
  el.onKeyUp.listen((_) => validate());
}

validate() {
  var intValue =
      int.parse(el.value, onError: (_) => null);
  if (el.value == "" || intValue != null) {
    el.classes.remove("wrong");
  } else {
    el.classes.add("wrong");
  }
}

// Tell Angular about directive we made.
ngBootstrap(new Module()
  ..type(Capitalize)
  ..type(MyIntegerValidator));


// Why constructor looks this way?
MyIntegerValidator(dom.Element this.el) {
  // ...
}

// Can we ask for more than an element itself?
MyIntegerValidator(dom.Element this.el) {
  // ...
}

Dependency Injection


// We can ask for services (@NgInjectableService)
// or for other directives on this element, etc.
// Injection is type based.
MyIntegerValidator(dom.Element this.el, Http http) {
  // ...
}

Components


@NgComponent(
    selector: 'hljs',
    templateUrl: 'packages/NgTalk/hljs/hljs.html',
    cssUrl: 'packages/NgTalk/hljs/hljs.css',
    resetStyleInheritance: true,
    map: const {
      "source": "@source"
    }
)
class HighlightJS {
  set source (val) => doHighlight(val);
}

<!-- packages/NgTalk/hljs/hljs.html -->
<div class="container"></div>

Shadow DOM

Controllers


@NgController(
  selector: '[slides]',
  publishAs: 'slides')
class SlidesController {
  // ...
}

Create scope

Define business logic

No DOM manipulation

Routes & Views


router.root
  ..addRoute(
      name: 'slideid',
      path: '/:slideId',
      enter: view('view/slideid.html'));

<!-- view/slideid.html -->
<h1 slide-id>Slide #{{ctrl.slideId}}</h1>

@NgController(
  selector: '[slide-id]',
  publishAs: 'ctrl')
class SlideIdController {
  final routeProvider;

  SlideIdController(RouteProvider this.routeProvider);

  get slideId => routeProvider.parameters['slideId'];
}

Those were the basics

There is more to it

Various built in directives, components, filters.

Everything is composable

angulardart.org

There are tutorials and samples there.

Polymer.dart?

It's all about
custom elements


<polymer-element name="tabs">
  <template>
    <ul>
      <template repeat="{{item in items}}">
        <li on-click="{{hadler}}">{{item}}</li>
      </template>
    </ul>
  </template>
  <script type="application/dart" src="tabs.dart"></script>
</polymer-element>

<tabs></tabs>

@CustomTag('tabs')
class TabsElement extends PolymerElement {
  @observable var items = toObservable([]);

  enteredView() { /* */ }

  leftView() { /* */ }

  handler(event, detail, target) {
    // handle click.
  }
}

@CustomTag('tabs')
class TabsElement extends PolymerElement {
  @observable var items = toObservable([]);

  itemsChanged() {
    // Will be called automatically if items changes.
  }
}

@CustomTag('tabs')
class TabsElement extends PolymerElement {
  @published var items;
}

<tabs items="{{items}}"></tabs>

@CustomTag('tabs')
class TabsElement extends UListElement {
  // ...
}

Elements from Polymer.js are being ported to Dart


<polymer-ui-icon-button> <polymer-ui-accordion>
<polymer-ui-menu>        <polymer-ui-arrow>
<polymer-ui-menu-button> <polymer-ui-breadcrumbs>
<polymer-ui-menu-item>   <polymer-ui-card>
<polymer-ui-nav-arrow>   <polymer-ui-collapsible>
<polymer-ui-overlay>     <polymer-ui-dropdown>
<polymer-ui-pages>       <polymer-ui-dropup>
<polymer-ui-ratings>     <polymer-ui-field>
<polymer-ui-scaffold>    <polymer-ui-icon>
              

<polymer-ajax>         <polymer-localstorage>
<polymer-anchor-point> <polymer-media-query>
<polymer-animation>    <polymer-meta>
<polymer-collapse>     <polymer-mock-data>
<polymer-cookie>       <polymer-overlay>
<polymer-file>         <polymer-page>
<polymer-flex-layout>  <polymer-scrub>
<polymer-google-jsapi> <polymer-selection>
<polymer-grid-layout>  <polymer-selector>
<polymer-jsonp>        <polymer-shared-lib>
<polymer-key-helper>   <polymer-signals>
<polymer-layout>       <polymer-view-source-link>

Custom element
is just an Element.

Polymer.dart
+
AngularDart


<my-polymer-list ng-smth>
  <li ng-repeat="x in ctrl.xs">

  </li>
</my-polymer-list>

Thanks!
Q&A