fix(ivy): move HostListeners generation to factory function (#26480)

PR Close #26480
This commit is contained in:
Andrew Kushnir
2018-10-16 10:28:23 -07:00
committed by Matias Niemelä
parent c0bf222a05
commit 2a869271f6
7 changed files with 146 additions and 34 deletions

View File

@ -12,6 +12,7 @@ import {CompileReflector} from '../../compile_reflector';
import {BindingForm, convertActionBinding, convertPropertyBinding} from '../../compiler_util/expression_converter';
import {ConstantPool, DefinitionKind} from '../../constant_pool';
import * as core from '../../core';
import {ParsedEvent} from '../../expression_parser/ast';
import {LifecycleHooks} from '../../lifecycle_reflector';
import * as o from '../../output/output_ast';
import {typeSourceSpan} from '../../parse_util';
@ -49,6 +50,7 @@ function baseDirectiveFields(
type: meta.type,
deps: meta.deps,
injectFn: R3.directiveInject,
extraStatementFn: createFactoryExtraStatementsFn(meta, bindingParser)
});
definitionMap.set('factory', result.factory);
@ -634,26 +636,6 @@ function createHostBindingsFunction(
}
}
// Calculate host event bindings
const eventBindings =
bindingParser.createDirectiveHostEventAsts(directiveSummary, hostBindingSourceSpan);
if (eventBindings) {
for (const binding of eventBindings) {
const bindingExpr = convertActionBinding(
null, bindingContext, binding.handler, 'b', () => error('Unexpected interpolation'));
const bindingName = binding.name && sanitizeIdentifier(binding.name);
const typeName = meta.name;
const functionName =
typeName && bindingName ? `${typeName}_${bindingName}_HostBindingHandler` : null;
const handler = o.fn(
[new o.FnParam('$event', o.DYNAMIC_TYPE)],
[...bindingExpr.stmts, new o.ReturnStatement(bindingExpr.allowDefault)], o.INFERRED_TYPE,
null, functionName);
statements.push(
o.importExpr(R3.listener).callFn([o.literal(binding.name), handler]).toStmt());
}
}
if (statements.length > 0) {
const typeName = meta.name;
return o.fn(
@ -667,6 +649,32 @@ function createHostBindingsFunction(
return null;
}
function createFactoryExtraStatementsFn(meta: R3DirectiveMetadata, bindingParser: BindingParser):
((instance: o.Expression) => o.Statement[])|null {
const eventBindings =
bindingParser.createDirectiveHostEventAsts(metadataAsSummary(meta), meta.typeSourceSpan);
return eventBindings && eventBindings.length ?
(instance: o.Expression) => createHostListeners(instance, eventBindings, meta) :
null;
}
function createHostListeners(
bindingContext: o.Expression, eventBindings: ParsedEvent[],
meta: R3DirectiveMetadata): o.Statement[] {
return eventBindings.map(binding => {
const bindingExpr = convertActionBinding(
null, bindingContext, binding.handler, 'b', () => error('Unexpected interpolation'));
const bindingName = binding.name && sanitizeIdentifier(binding.name);
const typeName = meta.name;
const functionName =
typeName && bindingName ? `${typeName}_${bindingName}_HostBindingHandler` : null;
const handler = o.fn(
[new o.FnParam('$event', o.DYNAMIC_TYPE)], [...bindingExpr.render3Stmts], o.INFERRED_TYPE,
null, functionName);
return o.importExpr(R3.listener).callFn([o.literal(binding.name), handler]).toStmt();
});
}
function metadataAsSummary(meta: R3DirectiveMetadata): CompileDirectiveSummary {
// clang-format off
return {