fix(ivy): support multiple directives with the same selector (#27298)
Previously the concept of multiple directives with the same selector was not supported by ngtsc. This is due to the treatment of directives for a component as a Map from selector to the directive, which is an erroneous representation. Now the directives for a component are stored as an array which supports multiple directives with the same selector. Testing strategy: a new ngtsc_spec test asserts that multiple directives with the same selector are matched on an element. PR Close #27298
This commit is contained in:

committed by
Igor Minar

parent
c331fc6f0c
commit
412e47d311
@ -128,7 +128,7 @@ export interface R3ComponentMetadataFacade extends R3DirectiveMetadataFacade {
|
||||
animations: any[]|undefined;
|
||||
viewQueries: R3QueryMetadataFacade[];
|
||||
pipes: Map<string, any>;
|
||||
directives: Map<string, any>;
|
||||
directives: {selector: string, expression: any}[];
|
||||
styles: string[];
|
||||
encapsulation: ViewEncapsulation;
|
||||
viewProviders: Provider[]|null;
|
||||
|
@ -153,10 +153,10 @@ export interface R3ComponentMetadata extends R3DirectiveMetadata {
|
||||
pipes: Map<string, o.Expression>;
|
||||
|
||||
/**
|
||||
* A map of directive selectors to an expression referencing the directive type which are in the
|
||||
* A list of directive selectors and an expression referencing the directive type which are in the
|
||||
* scope of the compilation.
|
||||
*/
|
||||
directives: Map<string, o.Expression>;
|
||||
directives: {selector: string, expression: o.Expression}[];
|
||||
|
||||
/**
|
||||
* Whether to wrap the 'directives' and/or `pipes` array, if one is generated, in a closure.
|
||||
|
@ -231,11 +231,11 @@ export function compileComponentFromMetadata(
|
||||
// Generate the CSS matcher that recognize directive
|
||||
let directiveMatcher: SelectorMatcher|null = null;
|
||||
|
||||
if (meta.directives.size) {
|
||||
if (meta.directives.length > 0) {
|
||||
const matcher = new SelectorMatcher();
|
||||
meta.directives.forEach((expression, selector: string) => {
|
||||
for (const {selector, expression} of meta.directives) {
|
||||
matcher.addSelectables(CssSelector.parse(selector), expression);
|
||||
});
|
||||
}
|
||||
directiveMatcher = matcher;
|
||||
}
|
||||
|
||||
@ -375,7 +375,7 @@ export function compileComponentFromRender2(
|
||||
ngContentSelectors: render3Ast.ngContentSelectors,
|
||||
relativeContextFilePath: '',
|
||||
},
|
||||
directives: typeMapToExpressionMap(directiveTypeBySel, outputCtx),
|
||||
directives: [],
|
||||
pipes: typeMapToExpressionMap(pipeTypeByName, outputCtx),
|
||||
viewQueries: queriesFromGlobalMetadata(component.viewQueries, outputCtx),
|
||||
wrapDirectivesAndPipesInClosure: false,
|
||||
|
Reference in New Issue
Block a user