mirror of
https://github.com/angular/angular
synced 2026-05-24 09:28:37 +00:00
We can simplify signature of listenToDirectiveOutput by passing less arguments (some of them can be derived from already passed arguments). PR Close #60547
This commit is contained in:
parent
88d7b7c965
commit
5a59af0ef8
6 changed files with 24 additions and 54 deletions
|
|
@ -210,7 +210,7 @@ export function listenerInternal(
|
|||
(<any>existingListener).__ngLastListenerFn__ = listenerFn;
|
||||
processOutputs = false;
|
||||
} else {
|
||||
listenerFn = wrapListener(tNode, lView, context, listenerFn);
|
||||
listenerFn = wrapListener(tNode, lView, listenerFn);
|
||||
stashEventListener(target as RElement, eventName, listenerFn);
|
||||
const cleanupFn = renderer.listen(target as RElement, eventName, listenerFn);
|
||||
ngDevMode && ngDevMode.rendererAddEventListener++;
|
||||
|
|
@ -221,7 +221,7 @@ export function listenerInternal(
|
|||
} else {
|
||||
// Even if there is no native listener to add, we still need to wrap the listener so that OnPush
|
||||
// ancestors are marked dirty when an event occurs.
|
||||
listenerFn = wrapListener(tNode, lView, context, listenerFn);
|
||||
listenerFn = wrapListener(tNode, lView, listenerFn);
|
||||
}
|
||||
|
||||
if (processOutputs) {
|
||||
|
|
@ -232,33 +232,13 @@ export function listenerInternal(
|
|||
for (let i = 0; i < hostDirectiveOutputConfig.length; i += 2) {
|
||||
const index = hostDirectiveOutputConfig[i] as number;
|
||||
const lookupName = hostDirectiveOutputConfig[i + 1] as string;
|
||||
listenToOutput(
|
||||
tNode,
|
||||
tView,
|
||||
lView,
|
||||
index,
|
||||
lookupName,
|
||||
eventName,
|
||||
listenerFn,
|
||||
lCleanup,
|
||||
tCleanup,
|
||||
);
|
||||
listenToOutput(tNode, lView, index, lookupName, eventName, listenerFn);
|
||||
}
|
||||
}
|
||||
|
||||
if (outputConfig && outputConfig.length) {
|
||||
for (const index of outputConfig) {
|
||||
listenToOutput(
|
||||
tNode,
|
||||
tView,
|
||||
lView,
|
||||
index,
|
||||
eventName,
|
||||
eventName,
|
||||
listenerFn,
|
||||
lCleanup,
|
||||
tCleanup,
|
||||
);
|
||||
listenToOutput(tNode, lView, index, eventName, eventName, listenerFn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
import {assertIndexInRange} from '../../util/assert';
|
||||
import {DirectiveDef} from '../interfaces/definition';
|
||||
import {TNode} from '../interfaces/node';
|
||||
import {CONTEXT, LView, TVIEW, TView} from '../interfaces/view';
|
||||
import {LView, TVIEW} from '../interfaces/view';
|
||||
import {getOrCreateLViewCleanup, getOrCreateTViewCleanup} from '../util/view_utils';
|
||||
import {wrapListener} from './listeners';
|
||||
|
||||
|
|
@ -26,23 +26,19 @@ export function createOutputListener<T = unknown>(
|
|||
eventName: string,
|
||||
) {
|
||||
// TODO(pk): decouple checks from the actual binding
|
||||
const wrappedListener = wrapListener(tNode, lView, lView[CONTEXT], listenerFn);
|
||||
const wrappedListener = wrapListener(tNode, lView, listenerFn);
|
||||
|
||||
// TODO(pk): simplify signature of listenToDirectiveOutput
|
||||
listenToDirectiveOutput(tNode, lView[TVIEW], lView, targetDef, eventName, wrappedListener);
|
||||
listenToDirectiveOutput(tNode, lView, targetDef, eventName, wrappedListener);
|
||||
}
|
||||
|
||||
/** Listens to an output on a specific directive. */
|
||||
function listenToDirectiveOutput(
|
||||
tNode: TNode,
|
||||
tView: TView,
|
||||
lView: LView,
|
||||
target: DirectiveDef<unknown>,
|
||||
eventName: string,
|
||||
listenerFn: (e?: any) => any,
|
||||
): boolean {
|
||||
const tCleanup = tView.firstCreatePass ? getOrCreateTViewCleanup(tView) : null;
|
||||
const lCleanup = getOrCreateLViewCleanup(lView);
|
||||
let hostIndex: number | null = null;
|
||||
let hostDirectivesStart: number | null = null;
|
||||
let hostDirectivesEnd: number | null = null;
|
||||
|
|
@ -75,14 +71,11 @@ function listenToDirectiveOutput(
|
|||
hasOutput = true;
|
||||
listenToOutput(
|
||||
tNode,
|
||||
tView,
|
||||
lView,
|
||||
index,
|
||||
hostDirectiveOutputs[i + 1] as string,
|
||||
eventName,
|
||||
listenerFn,
|
||||
lCleanup,
|
||||
tCleanup,
|
||||
);
|
||||
} else if (index > hostDirectivesEnd) {
|
||||
break;
|
||||
|
|
@ -93,17 +86,7 @@ function listenToDirectiveOutput(
|
|||
if (target.outputs.hasOwnProperty(eventName)) {
|
||||
ngDevMode && assertIndexInRange(lView, hostIndex);
|
||||
hasOutput = true;
|
||||
listenToOutput(
|
||||
tNode,
|
||||
tView,
|
||||
lView,
|
||||
hostIndex,
|
||||
eventName,
|
||||
eventName,
|
||||
listenerFn,
|
||||
lCleanup,
|
||||
tCleanup,
|
||||
);
|
||||
listenToOutput(tNode, lView, hostIndex, eventName, eventName, listenerFn);
|
||||
}
|
||||
|
||||
return hasOutput;
|
||||
|
|
@ -111,18 +94,16 @@ function listenToDirectiveOutput(
|
|||
|
||||
export function listenToOutput(
|
||||
tNode: TNode,
|
||||
tView: TView,
|
||||
lView: LView,
|
||||
index: number,
|
||||
directiveIndex: number,
|
||||
lookupName: string,
|
||||
eventName: string,
|
||||
listenerFn: (e?: any) => any,
|
||||
lCleanup: any[],
|
||||
tCleanup: any[] | null,
|
||||
) {
|
||||
ngDevMode && assertIndexInRange(lView, index);
|
||||
const instance = lView[index];
|
||||
const def = tView.data[index] as DirectiveDef<unknown>;
|
||||
ngDevMode && assertIndexInRange(lView, directiveIndex);
|
||||
const instance = lView[directiveIndex];
|
||||
const tView = lView[TVIEW];
|
||||
const def = tView.data[directiveIndex] as DirectiveDef<unknown>;
|
||||
const propertyName = def.outputs[lookupName];
|
||||
const output = instance[propertyName];
|
||||
|
||||
|
|
@ -130,6 +111,9 @@ export function listenToOutput(
|
|||
throw new Error(`@Output ${propertyName} not initialized in '${instance.constructor.name}'.`);
|
||||
}
|
||||
|
||||
// TODO(pk): introduce utility to store cleanup or find a different way of sharing code with listener
|
||||
const tCleanup = tView.firstCreatePass ? getOrCreateTViewCleanup(tView) : null;
|
||||
const lCleanup = getOrCreateLViewCleanup(lView);
|
||||
const subscription = (output as SubscribableOutput<unknown>).subscribe(listenerFn);
|
||||
const idx = lCleanup.length;
|
||||
lCleanup.push(listenerFn, subscription);
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import {setActiveConsumer} from '@angular/core/primitives/signals';
|
|||
import {NotificationSource} from '../../change_detection/scheduling/zoneless_scheduling';
|
||||
import {TNode} from '../interfaces/node';
|
||||
import {isComponentHost} from '../interfaces/type_checks';
|
||||
import {INJECTOR, LView} from '../interfaces/view';
|
||||
import {CONTEXT, INJECTOR, LView} from '../interfaces/view';
|
||||
import {getComponentLViewByIndex} from '../util/view_utils';
|
||||
import {profiler} from '../profiler';
|
||||
import {ProfilerEvent} from '../profiler_types';
|
||||
|
|
@ -31,7 +31,6 @@ import {markViewDirty} from '../instructions/mark_view_dirty';
|
|||
export function wrapListener(
|
||||
tNode: TNode,
|
||||
lView: LView<{} | null>,
|
||||
context: {} | null,
|
||||
listenerFn: (e?: any) => any,
|
||||
): EventListener {
|
||||
// Note: we are performing most of the work in the listener function itself
|
||||
|
|
@ -48,6 +47,7 @@ export function wrapListener(
|
|||
const startView = isComponentHost(tNode) ? getComponentLViewByIndex(tNode.index, lView) : lView;
|
||||
markViewDirty(startView, NotificationSource.Listener);
|
||||
|
||||
const context = lView[CONTEXT];
|
||||
let result = executeListenerWithErrorHandling(lView, context, listenerFn, e);
|
||||
// A just-invoked listener function might have coalesced listeners so we need to check for
|
||||
// their presence and invoke as needed.
|
||||
|
|
|
|||
|
|
@ -388,8 +388,10 @@
|
|||
"getNodeInjectable",
|
||||
"getNullInjector",
|
||||
"getOrCreateInjectable",
|
||||
"getOrCreateLViewCleanup",
|
||||
"getOrCreateNodeInjectorForNode",
|
||||
"getOrCreateTNode",
|
||||
"getOrCreateTViewCleanup",
|
||||
"getOrCreateViewRefs",
|
||||
"getOwnDefinition",
|
||||
"getParentInjectorIndex",
|
||||
|
|
|
|||
|
|
@ -375,8 +375,10 @@
|
|||
"getNodeInjectable",
|
||||
"getNullInjector",
|
||||
"getOrCreateInjectable",
|
||||
"getOrCreateLViewCleanup",
|
||||
"getOrCreateNodeInjectorForNode",
|
||||
"getOrCreateTNode",
|
||||
"getOrCreateTViewCleanup",
|
||||
"getOrCreateViewRefs",
|
||||
"getOwnDefinition",
|
||||
"getParentInjectorIndex",
|
||||
|
|
|
|||
|
|
@ -319,8 +319,10 @@
|
|||
"getNodeInjectable",
|
||||
"getNullInjector",
|
||||
"getOrCreateInjectable",
|
||||
"getOrCreateLViewCleanup",
|
||||
"getOrCreateNodeInjectorForNode",
|
||||
"getOrCreateTNode",
|
||||
"getOrCreateTViewCleanup",
|
||||
"getOrCreateViewRefs",
|
||||
"getOwnDefinition",
|
||||
"getParentInjectorIndex",
|
||||
|
|
|
|||
Loading…
Reference in a new issue