fix(animations): properly recover and cleanup DOM when CD failures occur (#20719)

Closes #19093

PR Close #20719
This commit is contained in:
Matias Niemelä 2017-11-30 11:52:35 -08:00 committed by Jason Aden
parent 661fdcd3e2
commit 46aa0a1cf6
2 changed files with 52 additions and 3 deletions

View File

@ -255,9 +255,12 @@ export class ViewRef_ implements EmbeddedViewRef<any>, InternalViewRef {
if (fs.begin) {
fs.begin();
}
Services.checkAndUpdateView(this._view);
if (fs.end) {
fs.end();
try {
Services.checkAndUpdateView(this._view);
} finally {
if (fs.end) {
fs.end();
}
}
}
checkNoChanges(): void { Services.checkNoChangesView(this._view); }

View File

@ -3348,6 +3348,52 @@ export function main() {
expect(() => { TestBed.createComponent(Cmp); }).not.toThrowError();
});
it('should continue to clean up DOM-related animation artificats even if a compiler-level error is thrown midway',
() => {
@Component({
selector: 'if-cmp',
animations: [
trigger(
'foo',
[
transition('* => something', []),
]),
],
template: `
value = {{ foo[bar] }}
<div #contents>
<div *ngIf="exp">1</div>
<div *ngIf="exp" @foo>2</div>
<div *ngIf="exp" [@foo]="'123'">3</div>
</div>
`,
})
class Cmp {
exp: any = false;
@ViewChild('contents') public contents: any;
}
TestBed.configureTestingModule({declarations: [Cmp]});
const engine = TestBed.get(ɵAnimationEngine);
const fixture = TestBed.createComponent(Cmp);
const runCD = () => fixture.detectChanges();
const cmp = fixture.componentInstance;
cmp.exp = true;
expect(runCD).toThrow();
const contents = cmp.contents.nativeElement;
expect(contents.innerText.replace(/\s+/gm, '')).toEqual('123');
cmp.exp = false;
expect(runCD).toThrow();
expect(contents.innerText.trim()).toEqual('');
});
describe('errors for not using the animation module', () => {
beforeEach(() => {
TestBed.configureTestingModule({