fix(ivy): change detection strategy not being passed to compiler (#27753)
Fixes the defined change detection strategy not being passed to the compiler when a component is being compiled. PR Close #27753
This commit is contained in:
parent
4b70a4e905
commit
a833b98fd0
|
@ -134,10 +134,13 @@ export interface R3ComponentMetadataFacade extends R3DirectiveMetadataFacade {
|
||||||
encapsulation: ViewEncapsulation;
|
encapsulation: ViewEncapsulation;
|
||||||
viewProviders: Provider[]|null;
|
viewProviders: Provider[]|null;
|
||||||
interpolation?: [string, string];
|
interpolation?: [string, string];
|
||||||
|
changeDetection?: ChangeDetectionStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ViewEncapsulation = number;
|
export type ViewEncapsulation = number;
|
||||||
|
|
||||||
|
export type ChangeDetectionStrategy = number;
|
||||||
|
|
||||||
export interface R3QueryMetadataFacade {
|
export interface R3QueryMetadataFacade {
|
||||||
propertyName: string;
|
propertyName: string;
|
||||||
first: boolean;
|
first: boolean;
|
||||||
|
|
|
@ -130,6 +130,7 @@ export class CompilerFacadeImpl implements CompilerFacade {
|
||||||
styles: facade.styles || [],
|
styles: facade.styles || [],
|
||||||
encapsulation: facade.encapsulation as any,
|
encapsulation: facade.encapsulation as any,
|
||||||
interpolation: interpolationConfig,
|
interpolation: interpolationConfig,
|
||||||
|
changeDetection: facade.changeDetection,
|
||||||
animations: facade.animations != null ? new WrappedNodeExpr(facade.animations) : null,
|
animations: facade.animations != null ? new WrappedNodeExpr(facade.animations) : null,
|
||||||
viewProviders: facade.viewProviders != null ? new WrappedNodeExpr(facade.viewProviders) :
|
viewProviders: facade.viewProviders != null ? new WrappedNodeExpr(facade.viewProviders) :
|
||||||
null,
|
null,
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* found in the LICENSE file at https://angular.io/license
|
* found in the LICENSE file at https://angular.io/license
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ViewEncapsulation} from '../../core';
|
import {ViewEncapsulation, ChangeDetectionStrategy} from '../../core';
|
||||||
import {InterpolationConfig} from '../../ml_parser/interpolation_config';
|
import {InterpolationConfig} from '../../ml_parser/interpolation_config';
|
||||||
import * as o from '../../output/output_ast';
|
import * as o from '../../output/output_ast';
|
||||||
import {ParseSourceSpan} from '../../parse_util';
|
import {ParseSourceSpan} from '../../parse_util';
|
||||||
|
@ -184,14 +184,19 @@ export interface R3ComponentMetadata extends R3DirectiveMetadata {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether translation variable name should contain external message id
|
* Whether translation variable name should contain external message id
|
||||||
* (used by Closure Compiler's output of `goog.getMsg` for transition period)
|
* (used by Closure Compiler's output of `goog.getMsg` for transition period).
|
||||||
*/
|
*/
|
||||||
i18nUseExternalIds: boolean;
|
i18nUseExternalIds: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overrides the default interpolation start and end delimiters ({{ and }})
|
* Overrides the default interpolation start and end delimiters ({{ and }}).
|
||||||
*/
|
*/
|
||||||
interpolation: InterpolationConfig;
|
interpolation: InterpolationConfig;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strategy used for detecting changes in the component.
|
||||||
|
*/
|
||||||
|
changeDetection?: ChangeDetectionStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -251,6 +251,7 @@ export function compileComponentFromMetadata(
|
||||||
|
|
||||||
const directivesUsed = new Set<o.Expression>();
|
const directivesUsed = new Set<o.Expression>();
|
||||||
const pipesUsed = new Set<o.Expression>();
|
const pipesUsed = new Set<o.Expression>();
|
||||||
|
const changeDetection = meta.changeDetection;
|
||||||
|
|
||||||
const template = meta.template;
|
const template = meta.template;
|
||||||
const templateBuilder = new TemplateDefinitionBuilder(
|
const templateBuilder = new TemplateDefinitionBuilder(
|
||||||
|
@ -313,6 +314,11 @@ export function compileComponentFromMetadata(
|
||||||
'data', o.literalMap([{key: 'animation', value: meta.animations, quoted: false}]));
|
'data', o.literalMap([{key: 'animation', value: meta.animations, quoted: false}]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Only set the change detection flag if it's defined and it's not the default.
|
||||||
|
if (changeDetection != null && changeDetection !== core.ChangeDetectionStrategy.Default) {
|
||||||
|
definitionMap.set('changeDetection', o.literal(changeDetection));
|
||||||
|
}
|
||||||
|
|
||||||
// On the type side, remove newlines from the selector as it will need to fit into a TypeScript
|
// On the type side, remove newlines from the selector as it will need to fit into a TypeScript
|
||||||
// string literal, which must be on one line.
|
// string literal, which must be on one line.
|
||||||
const selectorForType = (meta.selector || '').replace(/\n/g, '');
|
const selectorForType = (meta.selector || '').replace(/\n/g, '');
|
||||||
|
|
|
@ -134,10 +134,13 @@ export interface R3ComponentMetadataFacade extends R3DirectiveMetadataFacade {
|
||||||
encapsulation: ViewEncapsulation;
|
encapsulation: ViewEncapsulation;
|
||||||
viewProviders: Provider[]|null;
|
viewProviders: Provider[]|null;
|
||||||
interpolation?: [string, string];
|
interpolation?: [string, string];
|
||||||
|
changeDetection?: ChangeDetectionStrategy;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ViewEncapsulation = number;
|
export type ViewEncapsulation = number;
|
||||||
|
|
||||||
|
export type ChangeDetectionStrategy = number;
|
||||||
|
|
||||||
export interface R3QueryMetadataFacade {
|
export interface R3QueryMetadataFacade {
|
||||||
propertyName: string;
|
propertyName: string;
|
||||||
first: boolean;
|
first: boolean;
|
||||||
|
|
|
@ -61,6 +61,7 @@ export function compileComponent(type: Type<any>, metadata: Component): void {
|
||||||
animations: metadata.animations,
|
animations: metadata.animations,
|
||||||
viewQueries: extractQueriesMetadata(type, getReflect().propMetadata(type), isViewQuery),
|
viewQueries: extractQueriesMetadata(type, getReflect().propMetadata(type), isViewQuery),
|
||||||
directives: [],
|
directives: [],
|
||||||
|
changeDetection: metadata.changeDetection,
|
||||||
pipes: new Map(),
|
pipes: new Map(),
|
||||||
encapsulation: metadata.encapsulation || ViewEncapsulation.Emulated,
|
encapsulation: metadata.encapsulation || ViewEncapsulation.Emulated,
|
||||||
interpolation: metadata.interpolation,
|
interpolation: metadata.interpolation,
|
||||||
|
|
|
@ -1297,9 +1297,7 @@ const TEST_COMPILER_PROVIDERS: Provider[] = [
|
||||||
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
fixmeIvy(
|
it('Reattaches in the original cd mode', fakeAsync(() => {
|
||||||
'FW-764: fixture.detectChanges() is not respecting OnPush flag on components in the root template')
|
|
||||||
.it('Reattaches in the original cd mode', fakeAsync(() => {
|
|
||||||
const ctx = createCompFixture('<push-cmp></push-cmp>');
|
const ctx = createCompFixture('<push-cmp></push-cmp>');
|
||||||
const cmp: PushComp = queryDirs(ctx.debugElement, PushComp)[0];
|
const cmp: PushComp = queryDirs(ctx.debugElement, PushComp)[0];
|
||||||
cmp.changeDetectorRef.detach();
|
cmp.changeDetectorRef.detach();
|
||||||
|
|
|
@ -585,9 +585,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
|
|
||||||
describe('OnPush components', () => {
|
describe('OnPush components', () => {
|
||||||
|
|
||||||
fixmeIvy(
|
it('should use ChangeDetectorRef to manually request a check', () => {
|
||||||
'FW-764: fixture.detectChanges() is not respecting OnPush flag on components in the root template')
|
|
||||||
.it('should use ChangeDetectorRef to manually request a check', () => {
|
|
||||||
TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithRef]]]});
|
TestBed.configureTestingModule({declarations: [MyComp, [[PushCmpWithRef]]]});
|
||||||
const template = '<push-cmp-with-ref #cmp></push-cmp-with-ref>';
|
const template = '<push-cmp-with-ref #cmp></push-cmp-with-ref>';
|
||||||
TestBed.overrideComponent(MyComp, {set: {template}});
|
TestBed.overrideComponent(MyComp, {set: {template}});
|
||||||
|
@ -607,9 +605,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
expect(cmp.numberOfChecks).toEqual(2);
|
expect(cmp.numberOfChecks).toEqual(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy(
|
it('should be checked when its bindings got updated', () => {
|
||||||
'FW-764: fixture.detectChanges() is not respecting OnPush flag on components in the root template')
|
|
||||||
.it('should be checked when its bindings got updated', () => {
|
|
||||||
TestBed.configureTestingModule(
|
TestBed.configureTestingModule(
|
||||||
{declarations: [MyComp, PushCmp, EventCmp], imports: [CommonModule]});
|
{declarations: [MyComp, PushCmp, EventCmp], imports: [CommonModule]});
|
||||||
const template = '<push-cmp [prop]="ctxProp" #cmp></push-cmp>';
|
const template = '<push-cmp [prop]="ctxProp" #cmp></push-cmp>';
|
||||||
|
@ -702,9 +698,7 @@ function declareTests(config?: {useJit: boolean}) {
|
||||||
expect(cmp.prop).toEqual('two');
|
expect(cmp.prop).toEqual('two');
|
||||||
});
|
});
|
||||||
|
|
||||||
fixmeIvy(
|
it('should be checked when an async pipe requests a check', fakeAsync(() => {
|
||||||
'FW-764: fixture.detectChanges() is not respecting OnPush flag on components in the root template')
|
|
||||||
.it('should be checked when an async pipe requests a check', fakeAsync(() => {
|
|
||||||
TestBed.configureTestingModule(
|
TestBed.configureTestingModule(
|
||||||
{declarations: [MyComp, PushCmpWithAsyncPipe], imports: [CommonModule]});
|
{declarations: [MyComp, PushCmpWithAsyncPipe], imports: [CommonModule]});
|
||||||
const template = '<push-cmp-with-async #cmp></push-cmp-with-async>';
|
const template = '<push-cmp-with-async #cmp></push-cmp-with-async>';
|
||||||
|
|
Loading…
Reference in New Issue