fix(animations): use a lightweight renderer for non-animation components (#17003)

This commit is contained in:
Matias Niemelä
2017-05-25 17:54:35 -07:00
committed by Chuck Jazdzewski
parent 2538094e13
commit 3ab86bd661
9 changed files with 277 additions and 87 deletions

View File

@ -1101,9 +1101,10 @@ export function main() {
const cmp = fixture.componentInstance;
const someTrigger = trigger('someTrigger', []);
const hostElement = fixture.nativeElement;
engine.register(DEFAULT_NAMESPACE_ID, hostElement);
engine.registerTrigger(
DEFAULT_COMPONENT_ID, DEFAULT_NAMESPACE_ID, fixture.nativeElement, someTrigger.name,
someTrigger);
DEFAULT_COMPONENT_ID, DEFAULT_NAMESPACE_ID, hostElement, someTrigger.name, someTrigger);
cmp.exp = 'a';
fixture.detectChanges();

View File

@ -1084,6 +1084,107 @@ export function main() {
]);
});
});
it('should query elements in sub components that do not contain animations using the :enter selector',
() => {
@Component({
selector: 'parent-cmp',
template: `
<div [@myAnimation]="exp">
<child-cmp #child></child-cmp>
</div>
`,
animations: [trigger(
'myAnimation',
[transition(
'* => on',
[query(
':enter', [style({opacity: 0}), animate(1000, style({opacity: 1}))])])])]
})
class ParentCmp {
public exp: any;
@ViewChild('child') public child: any;
}
@Component({
selector: 'child-cmp',
template: `
<div *ngFor="let item of items">
{{ item }}
</div>
`
})
class ChildCmp {
public items: any[] = [];
}
TestBed.configureTestingModule({declarations: [ParentCmp, ChildCmp]});
const fixture = TestBed.createComponent(ParentCmp);
const cmp = fixture.componentInstance;
fixture.detectChanges();
cmp.exp = 'on';
cmp.child.items = [1, 2, 3];
fixture.detectChanges();
const players = getLog() as any[];
expect(players.length).toEqual(3);
expect(players[0].element.innerText.trim()).toEqual('1');
expect(players[1].element.innerText.trim()).toEqual('2');
expect(players[2].element.innerText.trim()).toEqual('3');
});
it('should query elements in sub components that do not contain animations using the :leave selector',
() => {
@Component({
selector: 'parent-cmp',
template: `
<div [@myAnimation]="exp">
<child-cmp #child></child-cmp>
</div>
`,
animations: [trigger(
'myAnimation',
[transition(
'* => on', [query(':leave', [animate(1000, style({opacity: 0}))])])])]
})
class ParentCmp {
public exp: any;
@ViewChild('child') public child: any;
}
@Component({
selector: 'child-cmp',
template: `
<div *ngFor="let item of items">
{{ item }}
</div>
`
})
class ChildCmp {
public items: any[] = [];
}
TestBed.configureTestingModule({declarations: [ParentCmp, ChildCmp]});
const fixture = TestBed.createComponent(ParentCmp);
const cmp = fixture.componentInstance;
cmp.child.items = [4, 5, 6];
fixture.detectChanges();
cmp.exp = 'on';
cmp.child.items = [];
fixture.detectChanges();
const players = getLog() as any[];
expect(players.length).toEqual(3);
expect(players[0].element.innerText.trim()).toEqual('4');
expect(players[1].element.innerText.trim()).toEqual('5');
expect(players[2].element.innerText.trim()).toEqual('6');
});
});
describe('sub triggers', () => {

View File

@ -130,11 +130,13 @@ export function main() {
.map(de => de.injector.get(ManualViewportDirective));
expect(main.nativeElement).toHaveText('(, B)');
viewportDirectives.forEach(d => d.show());
main.detectChanges();
expect(main.nativeElement).toHaveText('(A1, B)');
viewportDirectives.forEach(d => d.hide());
main.detectChanges();
expect(main.nativeElement).toHaveText('(, B)');
});
@ -200,10 +202,11 @@ export function main() {
expect(main.nativeElement).toHaveText('(, BC)');
viewportDirective.show();
main.detectChanges();
expect(main.nativeElement).toHaveText('(A, BC)');
viewportDirective.hide();
main.detectChanges();
expect(main.nativeElement).toHaveText('(, BC)');
});
@ -492,7 +495,7 @@ export function main() {
expect(main.nativeElement).toHaveText('(, D)');
viewViewportDir.show();
main.detectChanges();
expect(main.nativeElement).toHaveText('(AC, D)');
const contentViewportDir =
@ -500,12 +503,13 @@ export function main() {
ManualViewportDirective);
contentViewportDir.show();
main.detectChanges();
expect(main.nativeElement).toHaveText('(ABC, D)');
// hide view viewport, and test that it also hides
// the content viewport's views
viewViewportDir.hide();
main.detectChanges();
expect(main.nativeElement).toHaveText('(, D)');
});
});

View File

@ -62,6 +62,7 @@ export function main() {
[elementDef(NodeFlags.None, null !, null !, 0, 'span', [['name', 'child1']])]))
]));
const viewContainerData = asElementData(parentView, 1);
const rf = parentView.root.rendererFactory;
const childView0 = createEmbeddedView(parentView, parentView.def.nodes[1]);
const childView1 = createEmbeddedView(parentView, parentView.def.nodes[2]);
@ -75,8 +76,10 @@ export function main() {
expect(getDOM().getAttribute(rootChildren[1], 'name')).toBe('child0');
expect(getDOM().getAttribute(rootChildren[2], 'name')).toBe('child1');
rf.begin !();
detachEmbeddedView(viewContainerData, 1);
detachEmbeddedView(viewContainerData, 0);
rf.end !();
expect(getDOM().childNodes(rootNodes[0]).length).toBe(2);
});
@ -187,4 +190,4 @@ export function main() {
expect(log).toEqual(['ngOnDestroy']);
});
});
}
}

View File

@ -121,6 +121,7 @@ export function main() {
])));
const componentView = asElementData(view, 0).componentView;
const rf = componentView.root.rendererFactory;
const view0 = createEmbeddedView(componentView, componentView.def.nodes[1]);
attachEmbeddedView(view, asElementData(componentView, 1), 0, view0);
@ -128,7 +129,9 @@ export function main() {
expect(getDOM().childNodes(getDOM().firstChild(rootNodes[0]))[1])
.toBe(asTextData(view, 2).renderText);
rf.begin !();
detachEmbeddedView(asElementData(componentView, 1), 0);
rf.end !();
expect(getDOM().childNodes(getDOM().firstChild(rootNodes[0])).length).toBe(1);
});