fix(core): support `ngFor` that has an `ngIf` as last node
Fixes #6304 Closes #6878
This commit is contained in:
parent
6ef2121e6a
commit
1779caf5f8
|
@ -338,6 +338,27 @@ function _flattenNestedViewRenderNodes(nodes: any[], renderNodes: any[]): any[]
|
||||||
return renderNodes;
|
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,
|
export function checkSlotCount(componentName: string, expectedSlotCount: number,
|
||||||
projectableNodes: any[][]): void {
|
projectableNodes: any[][]): void {
|
||||||
var givenSlotCount = isPresent(projectableNodes) ? projectableNodes.length : 0;
|
var givenSlotCount = isPresent(projectableNodes) ? projectableNodes.length : 0;
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
import {isPresent, isBlank, isArray} from 'angular2/src/facade/lang';
|
import {isPresent, isBlank, isArray} from 'angular2/src/facade/lang';
|
||||||
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper, StringMapWrapper} from 'angular2/src/facade/collection';
|
||||||
import {BaseException} from 'angular2/src/facade/exceptions';
|
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 {AppElement} from './element';
|
||||||
import {ElementRef, ElementRef_} from './element_ref';
|
import {ElementRef, ElementRef_} from './element_ref';
|
||||||
import {
|
import {
|
||||||
|
@ -344,12 +344,7 @@ export class AppViewManager_ extends AppViewManager {
|
||||||
refNode = vcAppElement.nativeElement;
|
refNode = vcAppElement.nativeElement;
|
||||||
}
|
}
|
||||||
if (isPresent(refNode)) {
|
if (isPresent(refNode)) {
|
||||||
var refRenderNode;
|
var refRenderNode = findLastRenderNode(refNode);
|
||||||
if (refNode instanceof AppElement) {
|
|
||||||
refRenderNode = (<AppElement>refNode).nativeElement;
|
|
||||||
} else {
|
|
||||||
refRenderNode = refNode;
|
|
||||||
}
|
|
||||||
view.renderer.attachViewAfter(refRenderNode,
|
view.renderer.attachViewAfter(refRenderNode,
|
||||||
flattenNestedViewRenderNodes(view.rootNodesOrAppElements));
|
flattenNestedViewRenderNodes(view.rootNodesOrAppElements));
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ import {
|
||||||
import {ListWrapper} from 'angular2/src/facade/collection';
|
import {ListWrapper} from 'angular2/src/facade/collection';
|
||||||
import {Component, View, TemplateRef, ContentChild} from 'angular2/core';
|
import {Component, View, TemplateRef, ContentChild} from 'angular2/core';
|
||||||
import {NgFor} from 'angular2/src/common/directives/ng_for';
|
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';
|
import {By} from 'angular2/platform/common_dom';
|
||||||
|
|
||||||
export function main() {
|
export function main() {
|
||||||
|
@ -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',
|
it('should display indices correctly',
|
||||||
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
inject([TestComponentBuilder, AsyncTestCompleter], (tcb: TestComponentBuilder, async) => {
|
||||||
var template =
|
var template =
|
||||||
|
@ -445,7 +473,7 @@ class Foo {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({selector: 'test-cmp'})
|
@Component({selector: 'test-cmp'})
|
||||||
@View({directives: [NgFor]})
|
@View({directives: [NgFor, NgIf]})
|
||||||
class TestComponent {
|
class TestComponent {
|
||||||
@ContentChild(TemplateRef) contentTpl: TemplateRef;
|
@ContentChild(TemplateRef) contentTpl: TemplateRef;
|
||||||
items: any;
|
items: any;
|
||||||
|
|
Loading…
Reference in New Issue