Skip to content

Commit a659259

Browse files
mheveryvicb
authored andcommitted
fix(core): detectChanges() doesn't work on detached instance
Closes angular#13426 Closes angular#13472
1 parent b56474d commit a659259

File tree

3 files changed

+34
-3
lines changed

3 files changed

+34
-3
lines changed

modules/@angular/compiler/src/view_compiler/view_builder.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ function generateDetectChangesMethod(view: CompileView): o.Statement[] {
576576
}
577577
stmts.push(...view.detectChangesRenderPropertiesMethod.finish());
578578
view.viewChildren.forEach((viewChild) => {
579-
stmts.push(viewChild.callMethod('detectChanges', [DetectChangesVars.throwOnChange]).toStmt());
579+
stmts.push(viewChild.callMethod('internalDetectChanges', [DetectChangesVars.throwOnChange]).toStmt());
580580
});
581581
const afterViewStmts =
582582
view.updateViewQueriesMethod.finish().concat(view.afterViewLifecycleCallbacksMethod.finish());

modules/@angular/core/src/linker/view.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -312,11 +312,16 @@ export abstract class AppView<T> {
312312
*/
313313
dirtyParentQueriesInternal(): void {}
314314

315+
internalDetectChanges(throwOnChange: boolean): void {
316+
if (this.cdMode !== ChangeDetectorStatus.Detached) {
317+
this.detectChanges(throwOnChange);
318+
}
319+
}
320+
315321
detectChanges(throwOnChange: boolean): void {
316322
const s = _scope_check(this.clazz);
317323
if (this.cdMode === ChangeDetectorStatus.Checked ||
318-
this.cdMode === ChangeDetectorStatus.Errored ||
319-
this.cdMode === ChangeDetectorStatus.Detached)
324+
this.cdMode === ChangeDetectorStatus.Errored)
320325
return;
321326
if (this.cdMode === ChangeDetectorStatus.Destroyed) {
322327
this.throwDestroyedError('detectChanges');

modules/@angular/core/test/linker/change_detection_integration_spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ export function main() {
8282
AnotherComponent,
8383
TestLocals,
8484
CompWithRef,
85+
WrapCompWithRef,
8586
EmitterDirective,
8687
PushComp,
8788
OnDestroyDirective,
@@ -1133,6 +1134,23 @@ export function main() {
11331134
expect(renderLog.log).toEqual([]);
11341135
}));
11351136

1137+
it('Detached view can be checked locally', fakeAsync(() => {
1138+
const ctx = createCompFixture('<wrap-comp-with-ref></wrap-comp-with-ref>');
1139+
const cmp: CompWithRef = queryDirs(ctx.debugElement, CompWithRef)[0];
1140+
cmp.value = 'hello';
1141+
cmp.changeDetectorRef.detach();
1142+
expect(renderLog.log).toEqual([]);
1143+
1144+
ctx.detectChanges();
1145+
1146+
expect(renderLog.log).toEqual([]);
1147+
1148+
cmp.changeDetectorRef.detectChanges();
1149+
1150+
expect(renderLog.log).toEqual(['{{hello}}']);
1151+
}));
1152+
1153+
11361154
it('Reattaches', fakeAsync(() => {
11371155
const ctx = createCompFixture('<comp-with-ref></comp-with-ref>');
11381156
const cmp: CompWithRef = queryDirs(ctx.debugElement, CompWithRef)[0];
@@ -1346,6 +1364,14 @@ class CompWithRef {
13461364
noop() {}
13471365
}
13481366

1367+
@Component({
1368+
selector: 'wrap-comp-with-ref',
1369+
template: '<comp-with-ref></comp-with-ref>'
1370+
})
1371+
class WrapCompWithRef {
1372+
constructor(public changeDetectorRef: ChangeDetectorRef) {}
1373+
}
1374+
13491375
@Component({
13501376
selector: 'push-cmp',
13511377
template: '<div (event)="noop()" emitterDirective></div>{{value}}{{renderIncrement}}',

0 commit comments

Comments
 (0)