From aa3769ba699a1747ecc504b60496d47481faf1fb Mon Sep 17 00:00:00 2001 From: Alex Rickabaugh Date: Wed, 14 Dec 2016 14:31:57 -0800 Subject: [PATCH] fix(compiler): resolver should merge host bindings and listeners (#13474) fixes #13327 --- .../compiler/src/directive_resolver.ts | 14 ++++---- .../compiler/test/directive_resolver_spec.ts | 35 +++++++++++++++++-- 2 files changed, 39 insertions(+), 10 deletions(-) diff --git a/modules/@angular/compiler/src/directive_resolver.ts b/modules/@angular/compiler/src/directive_resolver.ts index 2db755dfe3..8e2076f60d 100644 --- a/modules/@angular/compiler/src/directive_resolver.ts +++ b/modules/@angular/compiler/src/directive_resolver.ts @@ -75,9 +75,8 @@ export class DirectiveResolver { outputs.push(propName); } } - const hostBinding = - ListWrapper.findLast(propertyMetadata[propName], (a) => a instanceof HostBinding); - if (hostBinding) { + const hostBindings = propertyMetadata[propName].filter(a => a && a instanceof HostBinding); + hostBindings.forEach(hostBinding => { if (hostBinding.hostPropertyName) { const startWith = hostBinding.hostPropertyName[0]; if (startWith === '(') { @@ -90,13 +89,12 @@ export class DirectiveResolver { } else { host[`[${propName}]`] = propName; } - } - const hostListener = - ListWrapper.findLast(propertyMetadata[propName], (a) => a instanceof HostListener); - if (hostListener) { + }); + const hostListeners = propertyMetadata[propName].filter(a => a && a instanceof HostListener) + hostListeners.forEach(hostListener => { const args = hostListener.args || []; host[`(${hostListener.eventName})`] = `${propName}(${args.join(',')})`; - } + }); const query = ListWrapper.findLast(propertyMetadata[propName], (a) => a instanceof Query); if (query) { queries[propName] = query; diff --git a/modules/@angular/compiler/test/directive_resolver_spec.ts b/modules/@angular/compiler/test/directive_resolver_spec.ts index 8da2116e1e..8f37734797 100644 --- a/modules/@angular/compiler/test/directive_resolver_spec.ts +++ b/modules/@angular/compiler/test/directive_resolver_spec.ts @@ -309,7 +309,8 @@ export function main() { } const directiveMetadata = resolver.resolve(Child); - expect(directiveMetadata.host).toEqual({'[p1]': 'p1', '[p22]': 'p2', '[p3]': 'p3'}); + expect(directiveMetadata.host) + .toEqual({'[p1]': 'p1', '[p21]': 'p2', '[p22]': 'p2', '[p3]': 'p3'}); }); it('should support inheriting host listeners', () => { @@ -329,8 +330,38 @@ export function main() { } const directiveMetadata = resolver.resolve(Child); - expect(directiveMetadata.host).toEqual({'(p1)': 'p1()', '(p22)': 'p2()', '(p3)': 'p3()'}); + expect(directiveMetadata.host) + .toEqual({'(p1)': 'p1()', '(p21)': 'p2()', '(p22)': 'p2()', '(p3)': 'p3()'}); }); + + it('should combine host bindings and listeners during inheritance', () => { + @Directive({selector: 'p'}) + class Parent { + @HostListener('p11') @HostListener('p12') + p1() {} + + @HostBinding('p21') @HostBinding('p22') + p2: any; + } + + class Child extends Parent { + @HostListener('c1') + p1() {} + + @HostBinding('c2') + p2: any; + } + + const directiveMetadata = resolver.resolve(Child); + expect(directiveMetadata.host).toEqual({ + '(p11)': 'p1()', + '(p12)': 'p1()', + '(c1)': 'p1()', + '[p21]': 'p2', + '[p22]': 'p2', + '[c2]': 'p2' + }); + }) }); describe('queries', () => {