From 7b005bb9cf79fcad96d9b61340a8251aa1fded8a Mon Sep 17 00:00:00 2001 From: atscott Date: Wed, 10 Jun 2020 08:31:08 -0700 Subject: [PATCH] Revert "fix(elements): fire custom element output events during component initialization (#36161)" (#37524) This reverts commit e9bff5fe9f40d87b2164fc4f667f2cdd0afd4634. Failures were detected in Google tests due to this commit PR Close #37524 --- .../src/component-factory-strategy.ts | 21 +++++++-------- .../elements/src/create-custom-element.ts | 4 +-- .../test/component-factory-strategy_spec.ts | 27 ------------------- .../test/create-custom-element_spec.ts | 11 -------- 4 files changed, 11 insertions(+), 52 deletions(-) diff --git a/packages/elements/src/component-factory-strategy.ts b/packages/elements/src/component-factory-strategy.ts index 799cfba683..3e5fcc5212 100644 --- a/packages/elements/src/component-factory-strategy.ts +++ b/packages/elements/src/component-factory-strategy.ts @@ -7,8 +7,8 @@ */ import {ApplicationRef, ComponentFactory, ComponentFactoryResolver, ComponentRef, EventEmitter, Injector, OnChanges, SimpleChange, SimpleChanges, Type} from '@angular/core'; -import {merge, Observable, ReplaySubject} from 'rxjs'; -import {map, switchMap} from 'rxjs/operators'; +import {merge, Observable} from 'rxjs'; +import {map} from 'rxjs/operators'; import {NgElementStrategy, NgElementStrategyEvent, NgElementStrategyFactory} from './element-strategy'; import {extractProjectableNodes} from './extract-projectable-nodes'; @@ -43,11 +43,9 @@ export class ComponentNgElementStrategyFactory implements NgElementStrategyFacto * @publicApi */ export class ComponentNgElementStrategy implements NgElementStrategy { - // Subject of `NgElementStrategyEvent` observables corresponding to the component's outputs. - private eventEmitters = new ReplaySubject[]>(1); - /** Merged stream of the component's output events. */ - readonly events = this.eventEmitters.pipe(switchMap(emitters => merge(...emitters))); + // TODO(issue/24571): remove '!'. + events!: Observable; /** Reference to the component that was created on connect. */ private componentRef: ComponentRef|null = null; @@ -189,13 +187,12 @@ export class ComponentNgElementStrategy implements NgElementStrategy { /** Sets up listeners for the component's outputs so that the events stream emits the events. */ protected initializeOutputs(componentRef: ComponentRef): void { - const eventEmitters: Observable[] = - this.componentFactory.outputs.map(({propName, templateName}) => { - const emitter: EventEmitter = componentRef.instance[propName]; - return emitter.pipe(map(value => ({name: templateName, value}))); - }); + const eventEmitters = this.componentFactory.outputs.map(({propName, templateName}) => { + const emitter: EventEmitter = componentRef.instance[propName]; + return emitter.pipe(map(value => ({name: templateName, value}))); + }); - this.eventEmitters.next(eventEmitters); + this.events = merge(...eventEmitters); } /** Calls ngOnChanges with all the inputs that have changed since the last call. */ diff --git a/packages/elements/src/create-custom-element.ts b/packages/elements/src/create-custom-element.ts index be3c82e9b3..53b55890fe 100644 --- a/packages/elements/src/create-custom-element.ts +++ b/packages/elements/src/create-custom-element.ts @@ -187,13 +187,13 @@ export function createCustomElement

( } connectedCallback(): void { + this.ngElementStrategy.connect(this); + // Listen for events from the strategy and dispatch them as custom events this.ngElementEventsSubscription = this.ngElementStrategy.events.subscribe(e => { const customEvent = createCustomEvent(this.ownerDocument!, e.name, e.value); this.dispatchEvent(customEvent); }); - - this.ngElementStrategy.connect(this); } disconnectedCallback(): void { diff --git a/packages/elements/test/component-factory-strategy_spec.ts b/packages/elements/test/component-factory-strategy_spec.ts index 53c9fbd0fc..c05f6a08a5 100644 --- a/packages/elements/test/component-factory-strategy_spec.ts +++ b/packages/elements/test/component-factory-strategy_spec.ts @@ -41,33 +41,6 @@ describe('ComponentFactoryNgElementStrategy', () => { expect(strategyFactory.create(injector)).toBeTruthy(); }); - describe('before connected', () => { - it('should allow subscribing to output events', () => { - const events: NgElementStrategyEvent[] = []; - strategy.events.subscribe(e => events.push(e)); - - // No events before connecting (since `componentRef` is not even on the strategy yet). - componentRef.instance.output1.next('output-1a'); - componentRef.instance.output1.next('output-1b'); - componentRef.instance.output2.next('output-2a'); - expect(events).toEqual([]); - - // No events upon connecting (since events are not cached/played back). - strategy.connect(document.createElement('div')); - expect(events).toEqual([]); - - // Events emitted once connected. - componentRef.instance.output1.next('output-1c'); - componentRef.instance.output1.next('output-1d'); - componentRef.instance.output2.next('output-2b'); - expect(events).toEqual([ - {name: 'templateOutput1', value: 'output-1c'}, - {name: 'templateOutput1', value: 'output-1d'}, - {name: 'templateOutput2', value: 'output-2b'}, - ]); - }); - }); - describe('after connected', () => { beforeEach(() => { // Set up an initial value to make sure it is passed to the component diff --git a/packages/elements/test/create-custom-element_spec.ts b/packages/elements/test/create-custom-element_spec.ts index 1520b4faab..231b3f3a34 100644 --- a/packages/elements/test/create-custom-element_spec.ts +++ b/packages/elements/test/create-custom-element_spec.ts @@ -117,16 +117,6 @@ if (browserDetection.supportsCustomElements) { expect(eventValue).toEqual(null); }); - it('should listen to output events during initialization', () => { - const events: string[] = []; - - const element = new NgElementCtor(injector); - element.addEventListener('strategy-event', evt => events.push((evt as CustomEvent).detail)); - element.connectedCallback(); - - expect(events).toEqual(['connect']); - }); - it('should properly set getters/setters on the element', () => { const element = new NgElementCtor(injector); element.fooFoo = 'foo-foo-value'; @@ -265,7 +255,6 @@ if (browserDetection.supportsCustomElements) { events = new Subject(); connect(element: HTMLElement): void { - this.events.next({name: 'strategy-event', value: 'connect'}); this.connectedElement = element; }