Skip to content

Commit

Permalink
fix(core): correct order in ContentChildren query result (angular#18326)
Browse files Browse the repository at this point in the history
  • Loading branch information
marclaval authored and mhevery committed Aug 19, 2017
1 parent f2a2a6b commit f53f724
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
7 changes: 6 additions & 1 deletion packages/core/src/view/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,13 @@ function calcQueryValues(
if (nodeDef.flags & NodeFlags.TypeElement && nodeDef.element !.template &&
(nodeDef.element !.template !.nodeMatchedQueries & queryDef.filterId) ===
queryDef.filterId) {
// check embedded views that were attached at the place of their template.
const elementData = asElementData(view, i);
// check embedded views that were attached at the place of their template,
// but process child nodes first if some match the query (see issue #16568)
if ((nodeDef.childMatchedQueries & queryDef.filterId) === queryDef.filterId) {
calcQueryValues(view, i + 1, i + nodeDef.childCount, queryDef, values);
i += nodeDef.childCount;
}
if (nodeDef.flags & NodeFlags.EmbeddedViews) {
const embeddedViews = elementData.viewContainer !._embeddedViews;
for (let k = 0; k < embeddedViews.length; k++) {
Expand Down
20 changes: 20 additions & 0 deletions packages/core/test/linker/query_integration_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export function main() {
NeedsViewChild,
NeedsStaticContentAndViewChild,
NeedsContentChild,
DirectiveNeedsContentChild,
NeedsTpl,
NeedsNamedTpl,
TextDirective,
Expand Down Expand Up @@ -89,6 +90,20 @@ export function main() {
]);
});

it('should contain the first content child when target is on <ng-template> with embedded view (issue #16568)',
() => {
const template =
'<div directive-needs-content-child><ng-template text="foo" [ngIf]="true"><div text="bar"></div></ng-template></div>' +
'<needs-content-child #q><ng-template text="foo" [ngIf]="true"><div text="bar"></div></ng-template></needs-content-child>';
const view = createTestCmp(MyComp0, template);
view.detectChanges();
const q: NeedsContentChild = view.debugElement.children[1].references !['q'];
expect(q.child.text).toEqual('foo');
const directive: DirectiveNeedsContentChild =
view.debugElement.children[0].injector.get(DirectiveNeedsContentChild);
expect(directive.child.text).toEqual('foo');
});

it('should contain the first view child', () => {
const template = '<needs-view-child #q></needs-view-child>';
const view = createTestCmpAndDetectChanges(MyComp0, template);
Expand Down Expand Up @@ -650,6 +665,11 @@ class NeedsContentChild implements AfterContentInit, AfterContentChecked {
ngAfterContentChecked() { this.logs.push(['check', this.child ? this.child.text : null]); }
}

@Directive({selector: '[directive-needs-content-child]'})
class DirectiveNeedsContentChild {
@ContentChild(TextDirective) child: TextDirective;
}

@Component({selector: 'needs-view-child', template: `<div *ngIf="shouldShow" text="foo"></div>`})
class NeedsViewChild implements AfterViewInit, AfterViewChecked {
shouldShow: boolean = true;
Expand Down

0 comments on commit f53f724

Please sign in to comment.