Skip to content

Commit f43fba6

Browse files
smdunn809alxhub
authored andcommitted
fix(upgrade): correctly handle downgraded OnPush components (#22209)
Fixes #14286 PR Close #22209
1 parent 4473da7 commit f43fba6

File tree

2 files changed

+50
-1
lines changed

2 files changed

+50
-1
lines changed

packages/upgrade/src/common/downgrade_component_adapter.ts

+4
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export class DowngradeComponentAdapter {
2525
private componentRef: ComponentRef<any>;
2626
private component: any;
2727
private changeDetector: ChangeDetectorRef;
28+
private viewChangeDetector: ChangeDetectorRef;
2829

2930
constructor(
3031
private element: angular.IAugmentedJQuery, private attrs: angular.IAttributes,
@@ -60,6 +61,7 @@ export class DowngradeComponentAdapter {
6061

6162
this.componentRef =
6263
this.componentFactory.create(childInjector, projectableNodes, this.element[0]);
64+
this.viewChangeDetector = this.componentRef.injector.get(ChangeDetectorRef);
6365
this.changeDetector = this.componentRef.changeDetectorRef;
6466
this.component = this.componentRef.instance;
6567

@@ -139,6 +141,8 @@ export class DowngradeComponentAdapter {
139141
(<OnChanges>this.component).ngOnChanges(inputChanges !);
140142
}
141143

144+
this.viewChangeDetector.markForCheck();
145+
142146
// If opted out of propagating digests, invoke change detection when inputs change.
143147
if (!propagateDigest) {
144148
detectChanges();

packages/upgrade/test/static/integration/downgrade_component_spec.ts

+46-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
* found in the LICENSE file at https://angular.io/license
77
*/
88

9-
import {ChangeDetectorRef, Compiler, Component, ComponentFactoryResolver, Directive, ElementRef, EventEmitter, Injector, Input, NgModule, NgModuleRef, OnChanges, OnDestroy, Output, SimpleChanges, destroyPlatform} from '@angular/core';
9+
import {ChangeDetectionStrategy, ChangeDetectorRef, Compiler, Component, ComponentFactoryResolver, Directive, ElementRef, EventEmitter, Injector, Input, NgModule, NgModuleRef, OnChanges, OnDestroy, Output, SimpleChanges, destroyPlatform} from '@angular/core';
1010
import {async, fakeAsync, tick} from '@angular/core/testing';
1111
import {BrowserModule} from '@angular/platform-browser';
1212
import {platformBrowserDynamic} from '@angular/platform-browser-dynamic';
@@ -148,6 +148,51 @@ withEachNg1Version(() => {
148148
});
149149
}));
150150

151+
it('should bind properties to onpush components', async(() => {
152+
const ng1Module =
153+
angular.module('ng1', []).value('$exceptionHandler', (err: any) => {
154+
throw err;
155+
}).run(($rootScope: angular.IScope) => {
156+
$rootScope['dataB'] = 'B';
157+
});
158+
159+
@Component({
160+
selector: 'ng2',
161+
inputs: ['oneWayB'],
162+
template: 'oneWayB: {{oneWayB}}',
163+
changeDetection: ChangeDetectionStrategy.OnPush
164+
})
165+
166+
class Ng2Component {
167+
ngOnChangesCount = 0;
168+
oneWayB = '?';
169+
}
170+
171+
ng1Module.directive('ng2', downgradeComponent({
172+
component: Ng2Component,
173+
}));
174+
175+
@NgModule({
176+
declarations: [Ng2Component],
177+
entryComponents: [Ng2Component],
178+
imports: [BrowserModule, UpgradeModule]
179+
})
180+
class Ng2Module {
181+
ngDoBootstrap() {}
182+
}
183+
184+
const element = html(`
185+
<div>
186+
<ng2 [one-way-b]="dataB"></ng2>
187+
</div>`);
188+
189+
bootstrap(platformBrowserDynamic(), Ng2Module, element, ng1Module).then((upgrade) => {
190+
expect(multiTrim(document.body.textContent)).toEqual('oneWayB: B');
191+
$apply(upgrade, 'dataB= "everyone"');
192+
expect(multiTrim(document.body.textContent)).toEqual('oneWayB: everyone');
193+
});
194+
}));
195+
151196
it('should support two-way binding and event listener', async(() => {
152197
const listenerSpy = jasmine.createSpy('$rootScope.listener');
153198
const ng1Module = angular.module('ng1', []).run(($rootScope: angular.IScope) => {

0 commit comments

Comments
 (0)