Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Revert "fix(elements): fire custom element output events during compo… #37526

Merged
merged 1 commit into from Jun 10, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
21 changes: 9 additions & 12 deletions packages/elements/src/component-factory-strategy.ts
Expand Up @@ -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';
Expand Down Expand Up @@ -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<Observable<NgElementStrategyEvent>[]>(1);

/** Merged stream of the component's output events. */
readonly events = this.eventEmitters.pipe(switchMap(emitters => merge(...emitters)));
// TODO(issue/24571): remove '!'.
events!: Observable<NgElementStrategyEvent>;

/** Reference to the component that was created on connect. */
private componentRef: ComponentRef<any>|null = null;
Expand Down Expand Up @@ -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<any>): void {
const eventEmitters: Observable<NgElementStrategyEvent>[] =
this.componentFactory.outputs.map(({propName, templateName}) => {
const emitter: EventEmitter<any> = componentRef.instance[propName];
return emitter.pipe(map(value => ({name: templateName, value})));
});
const eventEmitters = this.componentFactory.outputs.map(({propName, templateName}) => {
const emitter: EventEmitter<any> = 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. */
Expand Down
4 changes: 2 additions & 2 deletions packages/elements/src/create-custom-element.ts
Expand Up @@ -187,13 +187,13 @@ export function createCustomElement<P>(
}

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 {
Expand Down
27 changes: 0 additions & 27 deletions packages/elements/test/component-factory-strategy_spec.ts
Expand Up @@ -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
Expand Down
11 changes: 0 additions & 11 deletions packages/elements/test/create-custom-element_spec.ts
Expand Up @@ -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';
Expand Down Expand Up @@ -265,7 +255,6 @@ if (browserDetection.supportsCustomElements) {
events = new Subject<NgElementStrategyEvent>();

connect(element: HTMLElement): void {
this.events.next({name: 'strategy-event', value: 'connect'});
this.connectedElement = element;
}

Expand Down