Skip to content

Commit

Permalink
feat(templates): add input to polymer templates to call Angular methods
Browse files Browse the repository at this point in the history
  • Loading branch information
hotforfeature committed Apr 11, 2017
1 parent 05949c9 commit 79004ec
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 6 deletions.
32 changes: 32 additions & 0 deletions docs/polymer-templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,38 @@ export class PolyComponent {
}
```

## Method Host

When `<template>`s are used inside a Polymer element, method bindings in the template refer to methods of the host element. An Angular component does not automatically set this, which can be problematic for computed properties inside templates.

To get around this, `[polymer-template]` has a `methodHost` input to specify what should be used as the host for template methods.

```ts
import { Component } from '@angular/core';

@Component({
selector: 'app-poly',
template: `
<iron-list [items]="items" as="item">
<ng-template polymer-template [methodHost]="this">
<my-item item="[[item]]" color="[[getColor(item)]]"></my-item>
</ng-template>
</iron-list>
`
})
export class PolyComponent {
items = [
'one',
'two',
'three'
];

getColor(item: string) {
return item === 'one' ? 'blue' : 'red';
}
}
```

## Broken Templates

`enableLegacyTemplate` and `<template>` elements are not currently working.
Expand Down
21 changes: 15 additions & 6 deletions src/templates/polymer-template.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
import { Directive, Input, OnInit, TemplateRef, ViewContainerRef } from '@angular/core';

// TODO: Deprecate this in favor of enableLegacyTemplate: false Angular compiler option.
// At the moment, this option doesn't seem to be working correctly
Expand All @@ -10,17 +10,22 @@ import { Directive, TemplateRef, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[polymer-template]'
})
export class PolymerTemplateDirective {
constructor(public view: ViewContainerRef, public templateRef: TemplateRef<any>) {
export class PolymerTemplateDirective implements OnInit {
@Input() methodHost: any;

private template: HTMLTemplateElement;

constructor(view: ViewContainerRef, templateRef: TemplateRef<any>) {
const parentNode = (<HTMLElement>view.element.nativeElement).parentNode;
const template = document.createElement('template');
this.template = document.createElement('template');

const viewRef = view.createEmbeddedView(templateRef);
viewRef.rootNodes.forEach(rootNode => {
parentNode.removeChild(rootNode);
template.content.appendChild(rootNode);
this.template.content.appendChild(rootNode);
});

parentNode.appendChild(template);
parentNode.appendChild(this.template);

// Detach and re-attach the parent element. This will trigger any template attaching logic
// that a custom elements needs which Angular skipped when using <ng-template>
Expand All @@ -33,4 +38,8 @@ export class PolymerTemplateDirective {
hostNode.appendChild(parentNode);
}
}

ngOnInit() {
this.template['__dataHost'] = this.methodHost; // tslint:disable-line:no-string-literal
}
}

0 comments on commit 79004ec

Please sign in to comment.