Skip to content

Commit

Permalink
fix(templates): shim Polymer.TemplateStamp on method host to allow Po…
Browse files Browse the repository at this point in the history
…lymer event bindings
  • Loading branch information
hotforfeature committed May 26, 2017
1 parent 9c53d0e commit 48319bd
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 4 deletions.
30 changes: 30 additions & 0 deletions docs/polymer-templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,36 @@ export class PolyComponent {
}
```

### Events

Angular will parse attribute event bindings, such as `on-click` or `on-tap` and remove them from the template. If you are trying to bind an event to an Angular component method host, be sure to instruct Angular *not* to perform binding.

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

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

alertClick(e: MouseEvent) {
alert('Clicked on ' + e.target.item);
}
}
```

## Broken Templates

`enableLegacyTemplate` and `<template>` elements are not currently working.
Expand Down
32 changes: 29 additions & 3 deletions src/templates/polymer-template.directive.spec.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// tslint:disable:no-string-literal
import { Component, ElementRef, ViewChild } from '@angular/core';
import { ComponentFixture, TestBed, async } from '@angular/core/testing';
import {} from 'jasmine';
Expand Down Expand Up @@ -74,11 +75,36 @@ describe('PolymerTemplateDirective', () => {
it('should set template.__dataHost to methodHost', async(() => {
fixture.whenStable().then(() => {
fixture.detectChanges();
// tslint:disable-next-line:no-string-literal
expect(template['__dataHost']).toBe(fixture.componentInstance);
// tslint:disable-next-line:no-string-literal
const host = fixture.componentInstance;
expect(template['__dataHost']).toBe(host);
expect(firstSiblingTemplate['__dataHost']).toBeUndefined();
});
}));

it('should shim _addEventListenerToNode', async(() => {
fixture.whenStable().then(() => {
fixture.detectChanges();
const host = fixture.componentInstance;
expect(host['_addEventListenerToNode']).toEqual(jasmine.any(Function));
const node = document.createElement('div');
const handler = () => { /* noop */ };
spyOn(node, 'addEventListener');
host['_addEventListenerToNode'](node, 'click', handler);
expect(node.addEventListener).toHaveBeenCalledWith('click', handler);
});
}));

it('should shim _removeEventListenerFromNode', async(() => {
fixture.whenStable().then(() => {
fixture.detectChanges();
const host = fixture.componentInstance;
expect(host['_removeEventListenerFromNode']).toEqual(jasmine.any(Function));
const node = document.createElement('div');
const handler = () => { /* noop */ };
spyOn(node, 'removeEventListener');
host['_removeEventListenerFromNode'](node, 'click', handler);
expect(node.removeEventListener).toHaveBeenCalledWith('click', handler);
});
}));
});
});
17 changes: 16 additions & 1 deletion src/templates/polymer-template.directive.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// tslint:disable:no-string-literal
import { Directive, Input, OnInit, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({
Expand Down Expand Up @@ -34,6 +35,20 @@ export class PolymerTemplateDirective implements OnInit {
}

ngOnInit() {
this.template['__dataHost'] = this.methodHost; // tslint:disable-line:no-string-literal
if (this.methodHost) {
// Shim Polymer.TemplateStamp mixin. This allows event bindings in Polymer to be used, such
// as on-click
this.methodHost['_addEventListenerToNode'] = (node: HTMLElement, eventName: string,
handler: any) => {
node.addEventListener(eventName, handler);
};

this.methodHost['_removeEventListenerFromNode'] = (node: HTMLElement, eventName: string,
handler: any) => {
node.removeEventListener(eventName, handler);
};

this.template['__dataHost'] = this.methodHost;
}
}
}

0 comments on commit 48319bd

Please sign in to comment.