X Tutup
Skip to content

Commit 6d4bd5d

Browse files
committed
fix(render): recurse into components/embedded templates not until all elements in a view have been visited
Fixes #4551 Closes #4601
1 parent ff77230 commit 6d4bd5d

File tree

11 files changed

+294
-133
lines changed

11 files changed

+294
-133
lines changed

modules/angular2/src/core/compiler/command_compiler.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export class CommandCompiler {
7474

7575
interface CommandFactory<R> {
7676
createText(value: string, isBound: boolean, ngContentIndex: number): R;
77-
createNgContent(ngContentIndex: number): R;
77+
createNgContent(index: number, ngContentIndex: number): R;
7878
createBeginElement(name: string, attrNameAndValues: string[], eventTargetAndNames: string[],
7979
variableNameAndValues: string[], directives: CompileDirectiveMetadata[],
8080
isBound: boolean, ngContentIndex: number): R;
@@ -114,7 +114,9 @@ class RuntimeCommandFactory implements CommandFactory<TemplateCmd> {
114114
createText(value: string, isBound: boolean, ngContentIndex: number): TemplateCmd {
115115
return text(value, isBound, ngContentIndex);
116116
}
117-
createNgContent(ngContentIndex: number): TemplateCmd { return ngContent(ngContentIndex); }
117+
createNgContent(index: number, ngContentIndex: number): TemplateCmd {
118+
return ngContent(index, ngContentIndex);
119+
}
118120
createBeginElement(name: string, attrNameAndValues: string[], eventTargetAndNames: string[],
119121
variableNameAndValues: string[], directives: CompileDirectiveMetadata[],
120122
isBound: boolean, ngContentIndex: number): TemplateCmd {
@@ -169,8 +171,8 @@ class CodegenCommandFactory implements CommandFactory<string> {
169171
createText(value: string, isBound: boolean, ngContentIndex: number): string {
170172
return `${TEMPLATE_COMMANDS_MODULE_REF}text(${escapeSingleQuoteString(value)}, ${isBound}, ${ngContentIndex})`;
171173
}
172-
createNgContent(ngContentIndex: number): string {
173-
return `${TEMPLATE_COMMANDS_MODULE_REF}ngContent(${ngContentIndex})`;
174+
createNgContent(index: number, ngContentIndex: number): string {
175+
return `${TEMPLATE_COMMANDS_MODULE_REF}ngContent(${index}, ${ngContentIndex})`;
174176
}
175177
createBeginElement(name: string, attrNameAndValues: string[], eventTargetAndNames: string[],
176178
variableNameAndValues: string[], directives: CompileDirectiveMetadata[],
@@ -221,7 +223,7 @@ class CommandBuilderVisitor<R> implements TemplateAstVisitor {
221223

222224
visitNgContent(ast: NgContentAst, context: any): any {
223225
this.transitiveNgContentCount++;
224-
this.result.push(this.commandFactory.createNgContent(ast.ngContentIndex));
226+
this.result.push(this.commandFactory.createNgContent(ast.index, ast.ngContentIndex));
225227
return null;
226228
}
227229
visitEmbeddedTemplate(ast: EmbeddedTemplateAst, context: any): any {

modules/angular2/src/core/compiler/template_ast.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ export class DirectiveAst implements TemplateAst {
104104
}
105105

106106
export class NgContentAst implements TemplateAst {
107-
constructor(public ngContentIndex: number, public sourceInfo: string) {}
107+
constructor(public index: number, public ngContentIndex: number, public sourceInfo: string) {}
108108
visit(visitor: TemplateAstVisitor, context: any): any {
109109
return visitor.visitNgContent(this, context);
110110
}

modules/angular2/src/core/compiler/template_parser.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
9696
selectorMatcher: SelectorMatcher;
9797
errors: string[] = [];
9898
directivesIndex = new Map<CompileDirectiveMetadata, number>();
99+
ngContentCount: number = 0;
100+
99101
constructor(directives: CompileDirectiveMetadata[], private _exprParser: Parser,
100102
private _schemaRegistry: ElementSchemaRegistry) {
101103
this.selectorMatcher = new SelectorMatcher();
@@ -207,7 +209,8 @@ class TemplateParseVisitor implements HtmlAstVisitor {
207209
hasInlineTemplates ? null : component.findNgContentIndex(elementCssSelector);
208210
var parsedElement;
209211
if (preparsedElement.type === PreparsedElementType.NG_CONTENT) {
210-
parsedElement = new NgContentAst(elementNgContentIndex, element.sourceInfo);
212+
parsedElement =
213+
new NgContentAst(this.ngContentCount++, elementNgContentIndex, element.sourceInfo);
211214
} else if (isTemplateElement) {
212215
this._assertNoComponentsNorElementBindingsOnTemplate(directives, elementProps, events,
213216
element.sourceInfo);

modules/angular2/src/core/linker/template_commands.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,14 +72,14 @@ export function text(value: string, isBound: boolean, ngContentIndex: number): T
7272

7373
export class NgContentCmd implements TemplateCmd, RenderNgContentCmd {
7474
isBound: boolean = false;
75-
constructor(public ngContentIndex: number) {}
75+
constructor(public index: number, public ngContentIndex: number) {}
7676
visit(visitor: RenderCommandVisitor, context: any): any {
7777
return visitor.visitNgContent(this, context);
7878
}
7979
}
8080

81-
export function ngContent(ngContentIndex: number): NgContentCmd {
82-
return new NgContentCmd(ngContentIndex);
81+
export function ngContent(index: number, ngContentIndex: number): NgContentCmd {
82+
return new NgContentCmd(index, ngContentIndex);
8383
}
8484

8585
export interface IBeginElementCmd extends TemplateCmd, RenderBeginElementCmd {

modules/angular2/src/core/render/api.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,13 @@ export interface RenderBeginCmd extends RenderTemplateCmd {
8585

8686
export interface RenderTextCmd extends RenderBeginCmd { value: string; }
8787

88-
export interface RenderNgContentCmd { ngContentIndex: number; }
88+
export interface RenderNgContentCmd {
89+
// The index of this NgContent element
90+
index: number;
91+
// The index of the NgContent element into which this
92+
// NgContent element should be projected (if any)
93+
ngContentIndex: number;
94+
}
8995

9096
export interface RenderBeginElementCmd extends RenderBeginCmd {
9197
name: string;

0 commit comments

Comments
 (0)
X Tutup