fix(core): call lifecycle hooks for siblings in declaration order
This commit is contained in:
@ -906,12 +906,13 @@ function createTests({viewEngine}: {viewEngine: boolean}) {
|
||||
it('should be called in reverse order so the child is always notified before the parent',
|
||||
fakeAsync(() => {
|
||||
const ctx = createCompFixture(
|
||||
'<div testDirective="parent"><div testDirective="child"></div></div>');
|
||||
'<div testDirective="parent"><div testDirective="child"></div></div><div testDirective="sibling"></div>');
|
||||
|
||||
ctx.detectChanges(false);
|
||||
|
||||
expect(directiveLog.filter(['ngAfterContentChecked'])).toEqual([
|
||||
'child.ngAfterContentChecked', 'parent.ngAfterContentChecked'
|
||||
'child.ngAfterContentChecked', 'parent.ngAfterContentChecked',
|
||||
'sibling.ngAfterContentChecked'
|
||||
]);
|
||||
}));
|
||||
});
|
||||
@ -1018,12 +1019,12 @@ function createTests({viewEngine}: {viewEngine: boolean}) {
|
||||
it('should be called in reverse order so the child is always notified before the parent',
|
||||
fakeAsync(() => {
|
||||
const ctx = createCompFixture(
|
||||
'<div testDirective="parent"><div testDirective="child"></div></div>');
|
||||
'<div testDirective="parent"><div testDirective="child"></div></div><div testDirective="sibling"></div>');
|
||||
|
||||
ctx.detectChanges(false);
|
||||
|
||||
expect(directiveLog.filter(['ngAfterViewChecked'])).toEqual([
|
||||
'child.ngAfterViewChecked', 'parent.ngAfterViewChecked'
|
||||
'child.ngAfterViewChecked', 'parent.ngAfterViewChecked', 'sibling.ngAfterViewChecked'
|
||||
]);
|
||||
}));
|
||||
});
|
||||
@ -1061,13 +1062,13 @@ function createTests({viewEngine}: {viewEngine: boolean}) {
|
||||
it('should be called in reverse order so the child is always notified before the parent',
|
||||
fakeAsync(() => {
|
||||
const ctx = createCompFixture(
|
||||
'<div testDirective="parent"><div testDirective="child"></div></div>');
|
||||
'<div testDirective="parent"><div testDirective="child"></div></div><div testDirective="sibling"></div>');
|
||||
|
||||
ctx.detectChanges(false);
|
||||
ctx.destroy();
|
||||
|
||||
expect(directiveLog.filter(['ngOnDestroy'])).toEqual([
|
||||
'child.ngOnDestroy', 'parent.ngOnDestroy'
|
||||
'child.ngOnDestroy', 'parent.ngOnDestroy', 'sibling.ngOnDestroy'
|
||||
]);
|
||||
}));
|
||||
|
||||
|
@ -11,69 +11,6 @@ import {filterQueryId} from '@angular/core/src/view/util';
|
||||
|
||||
export function main() {
|
||||
describe('viewDef', () => {
|
||||
describe('reverseChild order', () => {
|
||||
function reverseChildOrder(viewDef: ViewDefinition): number[] {
|
||||
return viewDef.reverseChildNodes.map(node => node.index);
|
||||
}
|
||||
|
||||
it('should reverse child order for root nodes', () => {
|
||||
const vd = viewDef(ViewFlags.None, [
|
||||
textDef(null, ['a']), // level 0, index 0
|
||||
textDef(null, ['a']), // level 0, index 0
|
||||
]);
|
||||
|
||||
expect(reverseChildOrder(vd)).toEqual([1, 0]);
|
||||
});
|
||||
|
||||
it('should reverse child order for one level, one root', () => {
|
||||
const vd = viewDef(ViewFlags.None, [
|
||||
elementDef(NodeFlags.None, null, null, 2, 'span'), // level 0, index 0
|
||||
textDef(null, ['a']), // level 1, index 1
|
||||
textDef(null, ['a']), // level 1, index 2
|
||||
]);
|
||||
|
||||
expect(reverseChildOrder(vd)).toEqual([0, 2, 1]);
|
||||
});
|
||||
|
||||
it('should reverse child order for 1 level, 2 roots', () => {
|
||||
const vd = viewDef(ViewFlags.None, [
|
||||
elementDef(NodeFlags.None, null, null, 2, 'span'), // level 0, index 0
|
||||
textDef(null, ['a']), // level 1, index 1
|
||||
textDef(null, ['a']), // level 1, index 2
|
||||
elementDef(NodeFlags.None, null, null, 1, 'span'), // level 0, index 3
|
||||
textDef(null, ['a']), // level 1, index 4
|
||||
]);
|
||||
|
||||
expect(reverseChildOrder(vd)).toEqual([3, 4, 0, 2, 1]);
|
||||
});
|
||||
|
||||
it('should reverse child order for 2 levels', () => {
|
||||
const vd = viewDef(ViewFlags.None, [
|
||||
elementDef(NodeFlags.None, null, null, 4, 'span'), // level 0, index 0
|
||||
elementDef(NodeFlags.None, null, null, 1, 'span'), // level 1, index 1
|
||||
textDef(null, ['a']), // level 2, index 2
|
||||
elementDef(NodeFlags.None, null, null, 1, 'span'), // level 1, index 3
|
||||
textDef(null, ['a']), // level 2, index 4
|
||||
]);
|
||||
|
||||
expect(reverseChildOrder(vd)).toEqual([0, 3, 4, 1, 2]);
|
||||
});
|
||||
|
||||
it('should reverse child order for mixed levels', () => {
|
||||
const vd = viewDef(ViewFlags.None, [
|
||||
textDef(null, ['a']), // level 0, index 0
|
||||
elementDef(NodeFlags.None, null, null, 5, 'span'), // level 0, index 1
|
||||
textDef(null, ['a']), // level 1, index 2
|
||||
elementDef(NodeFlags.None, null, null, 1, 'span'), // level 1, index 3
|
||||
textDef(null, ['a']), // level 2, index 4
|
||||
elementDef(NodeFlags.None, null, null, 1, 'span'), // level 1, index 5
|
||||
textDef(null, ['a']), // level 2, index 6
|
||||
textDef(null, ['a']), // level 0, index 7
|
||||
]);
|
||||
|
||||
expect(reverseChildOrder(vd)).toEqual([7, 1, 5, 6, 3, 4, 2, 0]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('parent', () => {
|
||||
function parents(viewDef: ViewDefinition): number[] {
|
||||
@ -122,6 +59,10 @@ export function main() {
|
||||
return viewDef.nodes.map(node => node.childFlags);
|
||||
}
|
||||
|
||||
function directChildFlags(viewDef: ViewDefinition): number[] {
|
||||
return viewDef.nodes.map(node => node.directChildFlags);
|
||||
}
|
||||
|
||||
it('should calculate childFlags for one level', () => {
|
||||
const vd = viewDef(ViewFlags.None, [
|
||||
elementDef(NodeFlags.None, null, null, 1, 'span'),
|
||||
@ -131,6 +72,10 @@ export function main() {
|
||||
expect(childFlags(vd)).toEqual([
|
||||
NodeFlags.TypeDirective | NodeFlags.AfterContentChecked, NodeFlags.None
|
||||
]);
|
||||
|
||||
expect(directChildFlags(vd)).toEqual([
|
||||
NodeFlags.TypeDirective | NodeFlags.AfterContentChecked, NodeFlags.None
|
||||
]);
|
||||
});
|
||||
|
||||
it('should calculate childFlags for two levels', () => {
|
||||
@ -144,6 +89,11 @@ export function main() {
|
||||
NodeFlags.TypeElement | NodeFlags.TypeDirective | NodeFlags.AfterContentChecked,
|
||||
NodeFlags.TypeDirective | NodeFlags.AfterContentChecked, NodeFlags.None
|
||||
]);
|
||||
|
||||
expect(directChildFlags(vd)).toEqual([
|
||||
NodeFlags.TypeElement, NodeFlags.TypeDirective | NodeFlags.AfterContentChecked,
|
||||
NodeFlags.None
|
||||
]);
|
||||
});
|
||||
|
||||
it('should calculate childFlags for one level, multiple roots', () => {
|
||||
@ -160,6 +110,12 @@ export function main() {
|
||||
NodeFlags.TypeDirective | NodeFlags.AfterContentInit | NodeFlags.AfterViewChecked,
|
||||
NodeFlags.None, NodeFlags.None
|
||||
]);
|
||||
|
||||
expect(directChildFlags(vd)).toEqual([
|
||||
NodeFlags.TypeDirective | NodeFlags.AfterContentChecked, NodeFlags.None,
|
||||
NodeFlags.TypeDirective | NodeFlags.AfterContentInit | NodeFlags.AfterViewChecked,
|
||||
NodeFlags.None, NodeFlags.None
|
||||
]);
|
||||
});
|
||||
|
||||
it('should calculate childFlags for multiple levels', () => {
|
||||
@ -178,6 +134,13 @@ export function main() {
|
||||
NodeFlags.TypeDirective | NodeFlags.AfterContentInit | NodeFlags.AfterViewInit,
|
||||
NodeFlags.None, NodeFlags.None
|
||||
]);
|
||||
|
||||
expect(directChildFlags(vd)).toEqual([
|
||||
NodeFlags.TypeElement, NodeFlags.TypeDirective | NodeFlags.AfterContentChecked,
|
||||
NodeFlags.None,
|
||||
NodeFlags.TypeDirective | NodeFlags.AfterContentInit | NodeFlags.AfterViewInit,
|
||||
NodeFlags.None, NodeFlags.None
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
|
Reference in New Issue
Block a user