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
This commit is contained in:
parent
401ef71ae5
commit
7b005bb9cf
|
@ -7,8 +7,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ApplicationRef, ComponentFactory, ComponentFactoryResolver, ComponentRef, EventEmitter, Injector, OnChanges, SimpleChange, SimpleChanges, Type} from '@angular/core';
|
import {ApplicationRef, ComponentFactory, ComponentFactoryResolver, ComponentRef, EventEmitter, Injector, OnChanges, SimpleChange, SimpleChanges, Type} from '@angular/core';
|
||||||
import {merge, Observable, ReplaySubject} from 'rxjs';
|
import {merge, Observable} from 'rxjs';
|
||||||
import {map, switchMap} from 'rxjs/operators';
|
import {map} from 'rxjs/operators';
|
||||||
|
|
||||||
import {NgElementStrategy, NgElementStrategyEvent, NgElementStrategyFactory} from './element-strategy';
|
import {NgElementStrategy, NgElementStrategyEvent, NgElementStrategyFactory} from './element-strategy';
|
||||||
import {extractProjectableNodes} from './extract-projectable-nodes';
|
import {extractProjectableNodes} from './extract-projectable-nodes';
|
||||||
|
@ -43,11 +43,9 @@ export class ComponentNgElementStrategyFactory implements NgElementStrategyFacto
|
||||||
* @publicApi
|
* @publicApi
|
||||||
*/
|
*/
|
||||||
export class ComponentNgElementStrategy implements NgElementStrategy {
|
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. */
|
/** 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. */
|
/** Reference to the component that was created on connect. */
|
||||||
private componentRef: ComponentRef<any>|null = null;
|
private componentRef: ComponentRef<any>|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. */
|
/** Sets up listeners for the component's outputs so that the events stream emits the events. */
|
||||||
protected initializeOutputs(componentRef: ComponentRef<any>): void {
|
protected initializeOutputs(componentRef: ComponentRef<any>): void {
|
||||||
const eventEmitters: Observable<NgElementStrategyEvent>[] =
|
const eventEmitters = this.componentFactory.outputs.map(({propName, templateName}) => {
|
||||||
this.componentFactory.outputs.map(({propName, templateName}) => {
|
|
||||||
const emitter: EventEmitter<any> = componentRef.instance[propName];
|
const emitter: EventEmitter<any> = componentRef.instance[propName];
|
||||||
return emitter.pipe(map(value => ({name: templateName, value})));
|
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. */
|
/** Calls ngOnChanges with all the inputs that have changed since the last call. */
|
||||||
|
|
|
@ -187,13 +187,13 @@ export function createCustomElement<P>(
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback(): void {
|
connectedCallback(): void {
|
||||||
|
this.ngElementStrategy.connect(this);
|
||||||
|
|
||||||
// Listen for events from the strategy and dispatch them as custom events
|
// Listen for events from the strategy and dispatch them as custom events
|
||||||
this.ngElementEventsSubscription = this.ngElementStrategy.events.subscribe(e => {
|
this.ngElementEventsSubscription = this.ngElementStrategy.events.subscribe(e => {
|
||||||
const customEvent = createCustomEvent(this.ownerDocument!, e.name, e.value);
|
const customEvent = createCustomEvent(this.ownerDocument!, e.name, e.value);
|
||||||
this.dispatchEvent(customEvent);
|
this.dispatchEvent(customEvent);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.ngElementStrategy.connect(this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback(): void {
|
disconnectedCallback(): void {
|
||||||
|
|
|
@ -41,33 +41,6 @@ describe('ComponentFactoryNgElementStrategy', () => {
|
||||||
expect(strategyFactory.create(injector)).toBeTruthy();
|
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', () => {
|
describe('after connected', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
// Set up an initial value to make sure it is passed to the component
|
// Set up an initial value to make sure it is passed to the component
|
||||||
|
|
|
@ -117,16 +117,6 @@ if (browserDetection.supportsCustomElements) {
|
||||||
expect(eventValue).toEqual(null);
|
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', () => {
|
it('should properly set getters/setters on the element', () => {
|
||||||
const element = new NgElementCtor(injector);
|
const element = new NgElementCtor(injector);
|
||||||
element.fooFoo = 'foo-foo-value';
|
element.fooFoo = 'foo-foo-value';
|
||||||
|
@ -265,7 +255,6 @@ if (browserDetection.supportsCustomElements) {
|
||||||
events = new Subject<NgElementStrategyEvent>();
|
events = new Subject<NgElementStrategyEvent>();
|
||||||
|
|
||||||
connect(element: HTMLElement): void {
|
connect(element: HTMLElement): void {
|
||||||
this.events.next({name: 'strategy-event', value: 'connect'});
|
|
||||||
this.connectedElement = element;
|
this.connectedElement = element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue