fix(ivy): init hooks being re-run if an exception is throw (#28024)
Fixes Ivy running the init hooks if an exception is thrown in one of them. These changes fix FW-830. PR Close #28024
This commit is contained in:
parent
3bafc002ae
commit
a6ba789599
|
@ -319,11 +319,14 @@ export function leaveView(newView: LView): void {
|
|||
if (isCreationMode(lView)) {
|
||||
lView[FLAGS] &= ~LViewFlags.CreationMode;
|
||||
} else {
|
||||
executeHooks(lView, tView.viewHooks, tView.viewCheckHooks, checkNoChangesMode);
|
||||
// Views are clean and in update mode after being checked, so these bits are cleared
|
||||
lView[FLAGS] &= ~(LViewFlags.Dirty | LViewFlags.FirstLViewPass);
|
||||
lView[FLAGS] |= LViewFlags.RunInit;
|
||||
lView[BINDING_INDEX] = tView.bindingStartIndex;
|
||||
try {
|
||||
executeHooks(lView, tView.viewHooks, tView.viewCheckHooks, checkNoChangesMode);
|
||||
} finally {
|
||||
// Views are clean and in update mode after being checked, so these bits are cleared
|
||||
lView[FLAGS] &= ~(LViewFlags.Dirty | LViewFlags.FirstLViewPass);
|
||||
lView[FLAGS] |= LViewFlags.RunInit;
|
||||
lView[BINDING_INDEX] = tView.bindingStartIndex;
|
||||
}
|
||||
}
|
||||
enterView(newView, null);
|
||||
}
|
||||
|
|
|
@ -1022,33 +1022,31 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
|||
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual([]);
|
||||
}));
|
||||
|
||||
fixmeIvy(
|
||||
'FW-830: Exception thrown in ngAfterViewInit triggers ngAfterViewInit re-execution')
|
||||
.it('should not call ngAfterViewInit again if it throws', fakeAsync(() => {
|
||||
const ctx = createCompFixture(
|
||||
'<div testDirective="dir" throwOn="ngAfterViewInit"></div>');
|
||||
it('should not call ngAfterViewInit again if it throws', fakeAsync(() => {
|
||||
const ctx =
|
||||
createCompFixture('<div testDirective="dir" throwOn="ngAfterViewInit"></div>');
|
||||
|
||||
let errored = false;
|
||||
// First pass fails, but ngAfterViewInit should be called.
|
||||
try {
|
||||
ctx.detectChanges(false);
|
||||
} catch (e) {
|
||||
errored = true;
|
||||
}
|
||||
expect(errored).toBe(true);
|
||||
let errored = false;
|
||||
// First pass fails, but ngAfterViewInit should be called.
|
||||
try {
|
||||
ctx.detectChanges(false);
|
||||
} catch (e) {
|
||||
errored = true;
|
||||
}
|
||||
expect(errored).toBe(true);
|
||||
|
||||
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual(['dir.ngAfterViewInit']);
|
||||
directiveLog.clear();
|
||||
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual(['dir.ngAfterViewInit']);
|
||||
directiveLog.clear();
|
||||
|
||||
// Second change detection also fails, but this time ngAfterViewInit should not be
|
||||
// called.
|
||||
try {
|
||||
ctx.detectChanges(false);
|
||||
} catch (e) {
|
||||
throw new Error('Second detectChanges() should not have run detection.');
|
||||
}
|
||||
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual([]);
|
||||
}));
|
||||
// Second change detection also fails, but this time ngAfterViewInit should not be
|
||||
// called.
|
||||
try {
|
||||
ctx.detectChanges(false);
|
||||
} catch (e) {
|
||||
throw new Error('Second detectChanges() should not have run detection.');
|
||||
}
|
||||
expect(directiveLog.filter(['ngAfterViewInit'])).toEqual([]);
|
||||
}));
|
||||
});
|
||||
|
||||
describe('ngAfterViewChecked', () => {
|
||||
|
|
Loading…
Reference in New Issue