fix(core): detectChanges() doesn't work on detached instance
Closes #13426 Closes #13472
This commit is contained in:
parent
b56474d067
commit
a659259962
|
@ -576,7 +576,7 @@ function generateDetectChangesMethod(view: CompileView): o.Statement[] {
|
|||
}
|
||||
stmts.push(...view.detectChangesRenderPropertiesMethod.finish());
|
||||
view.viewChildren.forEach((viewChild) => {
|
||||
stmts.push(viewChild.callMethod('detectChanges', [DetectChangesVars.throwOnChange]).toStmt());
|
||||
stmts.push(viewChild.callMethod('internalDetectChanges', [DetectChangesVars.throwOnChange]).toStmt());
|
||||
});
|
||||
const afterViewStmts =
|
||||
view.updateViewQueriesMethod.finish().concat(view.afterViewLifecycleCallbacksMethod.finish());
|
||||
|
|
|
@ -312,11 +312,16 @@ export abstract class AppView<T> {
|
|||
*/
|
||||
dirtyParentQueriesInternal(): void {}
|
||||
|
||||
internalDetectChanges(throwOnChange: boolean): void {
|
||||
if (this.cdMode !== ChangeDetectorStatus.Detached) {
|
||||
this.detectChanges(throwOnChange);
|
||||
}
|
||||
}
|
||||
|
||||
detectChanges(throwOnChange: boolean): void {
|
||||
const s = _scope_check(this.clazz);
|
||||
if (this.cdMode === ChangeDetectorStatus.Checked ||
|
||||
this.cdMode === ChangeDetectorStatus.Errored ||
|
||||
this.cdMode === ChangeDetectorStatus.Detached)
|
||||
this.cdMode === ChangeDetectorStatus.Errored)
|
||||
return;
|
||||
if (this.cdMode === ChangeDetectorStatus.Destroyed) {
|
||||
this.throwDestroyedError('detectChanges');
|
||||
|
|
|
@ -82,6 +82,7 @@ export function main() {
|
|||
AnotherComponent,
|
||||
TestLocals,
|
||||
CompWithRef,
|
||||
WrapCompWithRef,
|
||||
EmitterDirective,
|
||||
PushComp,
|
||||
OnDestroyDirective,
|
||||
|
@ -1133,6 +1134,23 @@ export function main() {
|
|||
expect(renderLog.log).toEqual([]);
|
||||
}));
|
||||
|
||||
it('Detached view can be checked locally', fakeAsync(() => {
|
||||
const ctx = createCompFixture('<wrap-comp-with-ref></wrap-comp-with-ref>');
|
||||
const cmp: CompWithRef = queryDirs(ctx.debugElement, CompWithRef)[0];
|
||||
cmp.value = 'hello';
|
||||
cmp.changeDetectorRef.detach();
|
||||
expect(renderLog.log).toEqual([]);
|
||||
|
||||
ctx.detectChanges();
|
||||
|
||||
expect(renderLog.log).toEqual([]);
|
||||
|
||||
cmp.changeDetectorRef.detectChanges();
|
||||
|
||||
expect(renderLog.log).toEqual(['{{hello}}']);
|
||||
}));
|
||||
|
||||
|
||||
it('Reattaches', fakeAsync(() => {
|
||||
const ctx = createCompFixture('<comp-with-ref></comp-with-ref>');
|
||||
const cmp: CompWithRef = queryDirs(ctx.debugElement, CompWithRef)[0];
|
||||
|
@ -1346,6 +1364,14 @@ class CompWithRef {
|
|||
noop() {}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'wrap-comp-with-ref',
|
||||
template: '<comp-with-ref></comp-with-ref>'
|
||||
})
|
||||
class WrapCompWithRef {
|
||||
constructor(public changeDetectorRef: ChangeDetectorRef) {}
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'push-cmp',
|
||||
template: '<div (event)="noop()" emitterDirective></div>{{value}}{{renderIncrement}}',
|
||||
|
|
Loading…
Reference in New Issue