fix(render): recurse into components/embedded templates not until all elements in a view have been visited
Fixes #4551 Closes #4601
This commit is contained in:
@ -74,7 +74,7 @@ export class CommandCompiler {
|
||||
|
||||
interface CommandFactory<R> {
|
||||
createText(value: string, isBound: boolean, ngContentIndex: number): R;
|
||||
createNgContent(ngContentIndex: number): R;
|
||||
createNgContent(index: number, ngContentIndex: number): R;
|
||||
createBeginElement(name: string, attrNameAndValues: string[], eventTargetAndNames: string[],
|
||||
variableNameAndValues: string[], directives: CompileDirectiveMetadata[],
|
||||
isBound: boolean, ngContentIndex: number): R;
|
||||
@ -114,7 +114,9 @@ class RuntimeCommandFactory implements CommandFactory<TemplateCmd> {
|
||||
createText(value: string, isBound: boolean, ngContentIndex: number): TemplateCmd {
|
||||
return text(value, isBound, ngContentIndex);
|
||||
}
|
||||
createNgContent(ngContentIndex: number): TemplateCmd { return ngContent(ngContentIndex); }
|
||||
createNgContent(index: number, ngContentIndex: number): TemplateCmd {
|
||||
return ngContent(index, ngContentIndex);
|
||||
}
|
||||
createBeginElement(name: string, attrNameAndValues: string[], eventTargetAndNames: string[],
|
||||
variableNameAndValues: string[], directives: CompileDirectiveMetadata[],
|
||||
isBound: boolean, ngContentIndex: number): TemplateCmd {
|
||||
@ -169,8 +171,8 @@ class CodegenCommandFactory implements CommandFactory<string> {
|
||||
createText(value: string, isBound: boolean, ngContentIndex: number): string {
|
||||
return `${TEMPLATE_COMMANDS_MODULE_REF}text(${escapeSingleQuoteString(value)}, ${isBound}, ${ngContentIndex})`;
|
||||
}
|
||||
createNgContent(ngContentIndex: number): string {
|
||||
return `${TEMPLATE_COMMANDS_MODULE_REF}ngContent(${ngContentIndex})`;
|
||||
createNgContent(index: number, ngContentIndex: number): string {
|
||||
return `${TEMPLATE_COMMANDS_MODULE_REF}ngContent(${index}, ${ngContentIndex})`;
|
||||
}
|
||||
createBeginElement(name: string, attrNameAndValues: string[], eventTargetAndNames: string[],
|
||||
variableNameAndValues: string[], directives: CompileDirectiveMetadata[],
|
||||
@ -221,7 +223,7 @@ class CommandBuilderVisitor<R> implements TemplateAstVisitor {
|
||||
|
||||
visitNgContent(ast: NgContentAst, context: any): any {
|
||||
this.transitiveNgContentCount++;
|
||||
this.result.push(this.commandFactory.createNgContent(ast.ngContentIndex));
|
||||
this.result.push(this.commandFactory.createNgContent(ast.index, ast.ngContentIndex));
|
||||
return null;
|
||||
}
|
||||
visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any {
|
||||
|
@ -104,7 +104,7 @@ export class DirectiveAst implements TemplateAst {
|
||||
}
|
||||
|
||||
export class NgContentAst implements TemplateAst {
|
||||
constructor(public ngContentIndex: number, public sourceInfo: string) {}
|
||||
constructor(public index: number, public ngContentIndex: number, public sourceInfo: string) {}
|
||||
visit(visitor: TemplateAstVisitor, context: any): any {
|
||||
return visitor.visitNgContent(this, context);
|
||||
}
|
||||
|
@ -96,6 +96,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
selectorMatcher: SelectorMatcher;
|
||||
errors: string[] = [];
|
||||
directivesIndex = new Map<CompileDirectiveMetadata, number>();
|
||||
ngContentCount: number = 0;
|
||||
|
||||
constructor(directives: CompileDirectiveMetadata[], private _exprParser: Parser,
|
||||
private _schemaRegistry: ElementSchemaRegistry) {
|
||||
this.selectorMatcher = new SelectorMatcher();
|
||||
@ -207,7 +209,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
|
||||
hasInlineTemplates ? null : component.findNgContentIndex(elementCssSelector);
|
||||
var parsedElement;
|
||||
if (preparsedElement.type === PreparsedElementType.NG_CONTENT) {
|
||||
parsedElement = new NgContentAst(elementNgContentIndex, element.sourceInfo);
|
||||
parsedElement =
|
||||
new NgContentAst(this.ngContentCount++, elementNgContentIndex, element.sourceInfo);
|
||||
} else if (isTemplateElement) {
|
||||
this._assertNoComponentsNorElementBindingsOnTemplate(directives, elementProps, events,
|
||||
element.sourceInfo);
|
||||
|
Reference in New Issue
Block a user