Skip to content

Commit

Permalink
fix(core): support ngFor that has an ngIf as last node
Browse files Browse the repository at this point in the history
Fixes #6304
  • Loading branch information
tbosch committed Feb 11, 2016
1 parent 3d715a2 commit 85a814b
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 8 deletions.
21 changes: 21 additions & 0 deletions modules/angular2/src/core/linker/view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,27 @@ function _flattenNestedViewRenderNodes(nodes: any[], renderNodes: any[]): any[]
return renderNodes;
}

export function findLastRenderNode(node: any): any {
var lastNode;
if (node instanceof AppElement) {
var appEl = <AppElement>node;
lastNode = appEl.nativeElement;
if (isPresent(appEl.nestedViews)) {
// Note: Views might have no root nodes at all!
for (var i = appEl.nestedViews.length - 1; i >= 0; i--) {
var nestedView = appEl.nestedViews[i];
if (nestedView.rootNodesOrAppElements.length > 0) {
lastNode = findLastRenderNode(
nestedView.rootNodesOrAppElements[nestedView.rootNodesOrAppElements.length - 1]);
}
}
}
} else {
lastNode = node;
}
return lastNode;
}

export function checkSlotCount(componentName: string, expectedSlotCount: number,
projectableNodes: any[][]): void {
var givenSlotCount = isPresent(projectableNodes) ? projectableNodes.length : 0;
Expand Down
9 changes: 2 additions & 7 deletions modules/angular2/src/core/linker/view_manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
import {isPresent, isBlank, isArray} from 'angular2/src/facade/lang';
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
import {BaseException} from 'angular2/src/facade/exceptions';
import {AppView, HostViewFactory, flattenNestedViewRenderNodes} from './view';
import {AppView, HostViewFactory, flattenNestedViewRenderNodes, findLastRenderNode} from './view';
import {AppElement} from './element';
import {ElementRef, ElementRef_} from './element_ref';
import {
Expand Down Expand Up @@ -344,12 +344,7 @@ export class AppViewManager_ extends AppViewManager {
refNode = vcAppElement.nativeElement;
}
if (isPresent(refNode)) {
var refRenderNode;
if (refNode instanceof AppElement) {
refRenderNode = (<AppElement>refNode).nativeElement;
} else {
refRenderNode = refNode;
}
var refRenderNode = findLastRenderNode(refNode);
view.renderer.attachViewAfter(refRenderNode,
flattenNestedViewRenderNodes(view.rootNodesOrAppElements));
}
Expand Down
30 changes: 29 additions & 1 deletion modules/angular2/test/common/directives/ng_for_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {
import {ListWrapper} from 'angular2/src/facade/collection';
import {Component, View, TemplateRef, ContentChild} from 'angular2/core';
import {NgFor} from 'angular2/src/common/directives/ng_for';
import {NgIf} from 'angular2/src/common/directives/ng_if';
import {By} from 'angular2/platform/common_dom';

export function main() {
Expand Down Expand Up @@ -232,6 +233,33 @@ export function main() {
});
}));

it('should repeat over nested ngIf that are the last node in the ngFor temlate',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template =
`<div><template ngFor #item [ngForOf]="items" #i="index"><div>{{i}}|</div>` +
`<div *ngIf="i % 2 == 0">even|</div></template></div>`;

tcb.overrideTemplate(TestComponent, template)
.createAsync(TestComponent)
.then((fixture) => {
var el = fixture.debugElement.nativeElement;
var items = [1];
fixture.debugElement.componentInstance.items = items;
fixture.detectChanges();
expect(el).toHaveText('0|even|');

items.push(1);
fixture.detectChanges();
expect(el).toHaveText('0|even|1|');

items.push(1);
fixture.detectChanges();
expect(el).toHaveText('0|even|1|2|even|');

async.done();
});
}));

it('should display indices correctly',
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
var template =
Expand Down Expand Up @@ -427,7 +455,7 @@ class Foo {
}

@Component({selector: 'test-cmp'})
@View({directives: [NgFor]})
@View({directives: [NgFor, NgIf]})
class TestComponent {
@ContentChild(TemplateRef) contentTpl: TemplateRef;
items: any;
Expand Down

0 comments on commit 85a814b

Please sign in to comment.