feat(ivy): support providers and viewProviders (#25803)

PR Close #25803
This commit is contained in:
Marc Laval
2018-10-18 09:23:18 +02:00
committed by Matias Niemelä
parent 9dc52d9d04
commit b0476f308b
76 changed files with 4098 additions and 1645 deletions

View File

@ -175,7 +175,7 @@ export class Identifiers {
static InheritDefinitionFeature:
o.ExternalReference = {name: 'ɵInheritDefinitionFeature', moduleName: CORE};
static PublicFeature: o.ExternalReference = {name: 'ɵPublicFeature', moduleName: CORE};
static ProvidersFeature: o.ExternalReference = {name: 'ɵProvidersFeature', moduleName: CORE};
static listener: o.ExternalReference = {name: 'ɵlistener', moduleName: CORE};

View File

@ -103,6 +103,11 @@ export interface R3DirectiveMetadata {
* if any.
*/
exportAs: string|null;
/**
* The list of providers defined in the directive.
*/
providers: o.Expression|null;
}
/**
@ -180,6 +185,11 @@ export interface R3ComponentMetadata extends R3DirectiveMetadata {
* A collection of animation triggers that will be used in the component template.
*/
animations: o.Expression|null;
/**
* The list of view providers defined in the component.
*/
viewProviders: o.Expression|null;
}
/**

View File

@ -82,11 +82,30 @@ function baseDirectiveFields(
// e.g 'outputs: {a: 'a'}`
definitionMap.set('outputs', conditionallyCreateMapObjectLiteral(meta.outputs));
if (meta.exportAs !== null) {
definitionMap.set('exportAs', o.literal(meta.exportAs));
}
return {definitionMap, statements: result.statements};
}
/**
* Add features to the definition map.
*/
function addFeatures(
definitionMap: DefinitionMap, meta: R3DirectiveMetadata | R3ComponentMetadata) {
// e.g. `features: [NgOnChangesFeature]`
const features: o.Expression[] = [];
// TODO: add `PublicFeature` so that directives get registered to the DI - make this configurable
features.push(o.importExpr(R3.PublicFeature));
const providers = meta.providers;
const viewProviders = (meta as R3ComponentMetadata).viewProviders;
if (providers || viewProviders) {
const args = [providers || new o.LiteralArrayExpr([])];
if (viewProviders) {
args.push(viewProviders);
}
features.push(o.importExpr(R3.ProvidersFeature).callFn(args));
}
if (meta.usesInheritance) {
features.push(o.importExpr(R3.InheritDefinitionFeature));
@ -97,11 +116,6 @@ function baseDirectiveFields(
if (features.length) {
definitionMap.set('features', o.literalArr(features));
}
if (meta.exportAs !== null) {
definitionMap.set('exportAs', o.literal(meta.exportAs));
}
return {definitionMap, statements: result.statements};
}
/**
@ -111,6 +125,7 @@ export function compileDirectiveFromMetadata(
meta: R3DirectiveMetadata, constantPool: ConstantPool,
bindingParser: BindingParser): R3DirectiveDef {
const {definitionMap, statements} = baseDirectiveFields(meta, constantPool, bindingParser);
addFeatures(definitionMap, meta);
const expression = o.importExpr(R3.defineDirective).callFn([definitionMap.toLiteralMap()]);
// On the type side, remove newlines from the selector as it will need to fit into a TypeScript
@ -164,6 +179,7 @@ export function compileComponentFromMetadata(
meta: R3ComponentMetadata, constantPool: ConstantPool,
bindingParser: BindingParser): R3ComponentDef {
const {definitionMap, statements} = baseDirectiveFields(meta, constantPool, bindingParser);
addFeatures(definitionMap, meta);
const selector = meta.selector && CssSelector.parse(meta.selector);
const firstSelector = selector && selector[0];
@ -320,6 +336,8 @@ export function compileComponentFromRender2(
encapsulation:
(summary.template && summary.template.encapsulation) || core.ViewEncapsulation.Emulated,
animations: null,
viewProviders:
component.viewProviders.length > 0 ? new o.WrappedNodeExpr(component.viewProviders) : null
};
const res = compileComponentFromMetadata(meta, outputCtx.constantPool, bindingParser);
@ -362,6 +380,7 @@ function directiveMetadataFromGlobalMetadata(
outputs: directive.outputs,
usesInheritance: false,
exportAs: null,
providers: directive.providers.length > 0 ? new o.WrappedNodeExpr(directive.providers) : null
};
}
@ -451,11 +470,15 @@ function createContentQueriesFunction(
if (meta.queries.length) {
const statements: o.Statement[] = meta.queries.map((query: R3QueryMetadata) => {
const queryDefinition = createQueryDefinition(query, constantPool, null);
return o.importExpr(R3.registerContentQuery).callFn([queryDefinition]).toStmt();
return o.importExpr(R3.registerContentQuery)
.callFn([queryDefinition, o.variable('dirIndex')])
.toStmt();
});
const typeName = meta.name;
const parameters = [new o.FnParam('dirIndex', o.NUMBER_TYPE)];
return o.fn(
[], statements, o.INFERRED_TYPE, null, typeName ? `${typeName}_ContentQueries` : null);
parameters, statements, o.INFERRED_TYPE, null,
typeName ? `${typeName}_ContentQueries` : null);
}
return null;