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());
|
stmts.push(...view.detectChangesRenderPropertiesMethod.finish());
|
||||||
view.viewChildren.forEach((viewChild) => {
|
view.viewChildren.forEach((viewChild) => {
|
||||||
stmts.push(viewChild.callMethod('detectChanges', [DetectChangesVars.throwOnChange]).toStmt());
|
stmts.push(viewChild.callMethod('internalDetectChanges', [DetectChangesVars.throwOnChange]).toStmt());
|
||||||
});
|
});
|
||||||
const afterViewStmts =
|
const afterViewStmts =
|
||||||
view.updateViewQueriesMethod.finish().concat(view.afterViewLifecycleCallbacksMethod.finish());
|
view.updateViewQueriesMethod.finish().concat(view.afterViewLifecycleCallbacksMethod.finish());
|
||||||
|
|
|
@ -312,11 +312,16 @@ export abstract class AppView<T> {
|
||||||
*/
|
*/
|
||||||
dirtyParentQueriesInternal(): void {}
|
dirtyParentQueriesInternal(): void {}
|
||||||
|
|
||||||
|
internalDetectChanges(throwOnChange: boolean): void {
|
||||||
|
if (this.cdMode !== ChangeDetectorStatus.Detached) {
|
||||||
|
this.detectChanges(throwOnChange);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
detectChanges(throwOnChange: boolean): void {
|
detectChanges(throwOnChange: boolean): void {
|
||||||
const s = _scope_check(this.clazz);
|
const s = _scope_check(this.clazz);
|
||||||
if (this.cdMode === ChangeDetectorStatus.Checked ||
|
if (this.cdMode === ChangeDetectorStatus.Checked ||
|
||||||
this.cdMode === ChangeDetectorStatus.Errored ||
|
this.cdMode === ChangeDetectorStatus.Errored)
|
||||||
this.cdMode === ChangeDetectorStatus.Detached)
|
|
||||||
return;
|
return;
|
||||||
if (this.cdMode === ChangeDetectorStatus.Destroyed) {
|
if (this.cdMode === ChangeDetectorStatus.Destroyed) {
|
||||||
this.throwDestroyedError('detectChanges');
|
this.throwDestroyedError('detectChanges');
|
||||||
|
|
|
@ -82,6 +82,7 @@ export function main() {
|
||||||
AnotherComponent,
|
AnotherComponent,
|
||||||
TestLocals,
|
TestLocals,
|
||||||
CompWithRef,
|
CompWithRef,
|
||||||
|
WrapCompWithRef,
|
||||||
EmitterDirective,
|
EmitterDirective,
|
||||||
PushComp,
|
PushComp,
|
||||||
OnDestroyDirective,
|
OnDestroyDirective,
|
||||||
|
@ -1133,6 +1134,23 @@ export function main() {
|
||||||
expect(renderLog.log).toEqual([]);
|
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(() => {
|
it('Reattaches', fakeAsync(() => {
|
||||||
const ctx = createCompFixture('<comp-with-ref></comp-with-ref>');
|
const ctx = createCompFixture('<comp-with-ref></comp-with-ref>');
|
||||||
const cmp: CompWithRef = queryDirs(ctx.debugElement, CompWithRef)[0];
|
const cmp: CompWithRef = queryDirs(ctx.debugElement, CompWithRef)[0];
|
||||||
|
@ -1346,6 +1364,14 @@ class CompWithRef {
|
||||||
noop() {}
|
noop() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Component({
|
||||||
|
selector: 'wrap-comp-with-ref',
|
||||||
|
template: '<comp-with-ref></comp-with-ref>'
|
||||||
|
})
|
||||||
|
class WrapCompWithRef {
|
||||||
|
constructor(public changeDetectorRef: ChangeDetectorRef) {}
|
||||||
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'push-cmp',
|
selector: 'push-cmp',
|
||||||
template: '<div (event)="noop()" emitterDirective></div>{{value}}{{renderIncrement}}',
|
template: '<div (event)="noop()" emitterDirective></div>{{value}}{{renderIncrement}}',
|
||||||
|
|
Loading…
Reference in New Issue