refactor(ivy): remove inputsPropertyName (#22716)
Closes #22591 PR Close #22716
This commit is contained in:
parent
34e355a3b0
commit
bd9d4df735
|
@ -15,7 +15,7 @@ import {Type} from '../type';
|
||||||
import {resolveRendererType2} from '../view/util';
|
import {resolveRendererType2} from '../view/util';
|
||||||
|
|
||||||
import {diPublic} from './di';
|
import {diPublic} from './di';
|
||||||
import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs, PipeDef, PipeType} from './interfaces/definition';
|
import {ComponentDef, ComponentDefArgs, DirectiveDef, DirectiveDefArgs, DirectiveDefFeature, PipeDef} from './interfaces/definition';
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,7 +45,6 @@ export function defineComponent<T>(componentDefinition: ComponentDefArgs<T>): Co
|
||||||
h: componentDefinition.hostBindings || noop,
|
h: componentDefinition.hostBindings || noop,
|
||||||
attributes: componentDefinition.attributes || null,
|
attributes: componentDefinition.attributes || null,
|
||||||
inputs: invertObject(componentDefinition.inputs),
|
inputs: invertObject(componentDefinition.inputs),
|
||||||
inputsPropertyName: componentDefinition.inputsPropertyName || null,
|
|
||||||
outputs: invertObject(componentDefinition.outputs),
|
outputs: invertObject(componentDefinition.outputs),
|
||||||
rendererType: resolveRendererType2(componentDefinition.rendererType) || null,
|
rendererType: resolveRendererType2(componentDefinition.rendererType) || null,
|
||||||
exportAs: componentDefinition.exportAs,
|
exportAs: componentDefinition.exportAs,
|
||||||
|
@ -72,48 +71,73 @@ type OnChangesExpando = OnChanges & {
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function NgOnChangesFeature(definition: DirectiveDef<any>): void {
|
/**
|
||||||
const inputs = definition.inputs;
|
* Creates an NgOnChangesFeature function for a component's features list.
|
||||||
const proto = definition.type.prototype;
|
*
|
||||||
const inputsPropertyName = definition.inputsPropertyName;
|
* It accepts an optional map of minified input property names to original property names,
|
||||||
// Place where we will store SimpleChanges if there is a change
|
* if any input properties have a public alias.
|
||||||
Object.defineProperty(proto, PRIVATE_PREFIX, {value: undefined, writable: true});
|
*
|
||||||
for (let pubKey in inputs) {
|
* The NgOnChangesFeature function that is returned decorates a component with support for
|
||||||
const minKey = inputs[pubKey];
|
* the ngOnChanges lifecycle hook, so it should be included in any component that implements
|
||||||
const propertyName = inputsPropertyName && inputsPropertyName[minKey] || pubKey;
|
* that hook.
|
||||||
const privateMinKey = PRIVATE_PREFIX + minKey;
|
*
|
||||||
// Create a place where the actual value will be stored and make it non-enumerable
|
* Example usage:
|
||||||
Object.defineProperty(proto, privateMinKey, {value: undefined, writable: true});
|
*
|
||||||
|
* ```
|
||||||
|
* static ngComponentDef = defineComponent({
|
||||||
|
* ...
|
||||||
|
* inputs: {name: 'publicName'},
|
||||||
|
* features: [NgOnChangesFeature({name: 'name'})]
|
||||||
|
* });
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @param inputPropertyNames Map of input property names, if they are aliased
|
||||||
|
* @returns DirectiveDefFeature
|
||||||
|
*/
|
||||||
|
export function NgOnChangesFeature(inputPropertyNames?: {[key: string]: string}):
|
||||||
|
DirectiveDefFeature {
|
||||||
|
return function(definition: DirectiveDef<any>): void {
|
||||||
|
const inputs = definition.inputs;
|
||||||
|
const proto = definition.type.prototype;
|
||||||
|
// Place where we will store SimpleChanges if there is a change
|
||||||
|
Object.defineProperty(proto, PRIVATE_PREFIX, {value: undefined, writable: true});
|
||||||
|
for (let pubKey in inputs) {
|
||||||
|
const minKey = inputs[pubKey];
|
||||||
|
const propertyName = inputPropertyNames && inputPropertyNames[minKey] || pubKey;
|
||||||
|
const privateMinKey = PRIVATE_PREFIX + minKey;
|
||||||
|
// Create a place where the actual value will be stored and make it non-enumerable
|
||||||
|
Object.defineProperty(proto, privateMinKey, {value: undefined, writable: true});
|
||||||
|
|
||||||
const existingDesc = Object.getOwnPropertyDescriptor(proto, minKey);
|
const existingDesc = Object.getOwnPropertyDescriptor(proto, minKey);
|
||||||
|
|
||||||
// create a getter and setter for property
|
// create a getter and setter for property
|
||||||
Object.defineProperty(proto, minKey, {
|
Object.defineProperty(proto, minKey, {
|
||||||
get: function(this: OnChangesExpando) {
|
get: function(this: OnChangesExpando) {
|
||||||
return (existingDesc && existingDesc.get) ? existingDesc.get.call(this) :
|
return (existingDesc && existingDesc.get) ? existingDesc.get.call(this) :
|
||||||
this[privateMinKey];
|
this[privateMinKey];
|
||||||
},
|
},
|
||||||
set: function(this: OnChangesExpando, value: any) {
|
set: function(this: OnChangesExpando, value: any) {
|
||||||
let simpleChanges = this[PRIVATE_PREFIX];
|
let simpleChanges = this[PRIVATE_PREFIX];
|
||||||
let isFirstChange = simpleChanges === undefined;
|
let isFirstChange = simpleChanges === undefined;
|
||||||
if (simpleChanges == null) {
|
if (simpleChanges == null) {
|
||||||
simpleChanges = this[PRIVATE_PREFIX] = {};
|
simpleChanges = this[PRIVATE_PREFIX] = {};
|
||||||
|
}
|
||||||
|
simpleChanges[propertyName] = new SimpleChange(this[privateMinKey], value, isFirstChange);
|
||||||
|
(existingDesc && existingDesc.set) ? existingDesc.set.call(this, value) :
|
||||||
|
this[privateMinKey] = value;
|
||||||
}
|
}
|
||||||
simpleChanges[propertyName] = new SimpleChange(this[privateMinKey], value, isFirstChange);
|
});
|
||||||
(existingDesc && existingDesc.set) ? existingDesc.set.call(this, value) :
|
}
|
||||||
this[privateMinKey] = value;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// If an onInit hook is defined, it will need to wrap the ngOnChanges call
|
// If an onInit hook is defined, it will need to wrap the ngOnChanges call
|
||||||
// so the call order is changes-init-check in creation mode. In subsequent
|
// so the call order is changes-init-check in creation mode. In subsequent
|
||||||
// change detection runs, only the check wrapper will be called.
|
// change detection runs, only the check wrapper will be called.
|
||||||
if (definition.onInit != null) {
|
if (definition.onInit != null) {
|
||||||
definition.onInit = onChangesWrapper(definition.onInit);
|
definition.onInit = onChangesWrapper(definition.onInit);
|
||||||
}
|
}
|
||||||
|
|
||||||
definition.doCheck = onChangesWrapper(definition.doCheck);
|
definition.doCheck = onChangesWrapper(definition.doCheck);
|
||||||
|
};
|
||||||
|
|
||||||
function onChangesWrapper(delegateHook: (() => void) | null) {
|
function onChangesWrapper(delegateHook: (() => void) | null) {
|
||||||
return function(this: OnChangesExpando) {
|
return function(this: OnChangesExpando) {
|
||||||
|
|
|
@ -68,14 +68,6 @@ export interface DirectiveDef<T> {
|
||||||
*/
|
*/
|
||||||
readonly inputs: {[P in keyof T]: P};
|
readonly inputs: {[P in keyof T]: P};
|
||||||
|
|
||||||
/**
|
|
||||||
* A dictionary mapping the inputs' minified property names to the original unminified property
|
|
||||||
* names.
|
|
||||||
*
|
|
||||||
* An entry is added if and only if the alias is different from the property name.
|
|
||||||
*/
|
|
||||||
readonly inputsPropertyName: {[P in keyof T]: P};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A dictionary mapping the outputs' minified property names to their public API names, which
|
* A dictionary mapping the outputs' minified property names to their public API names, which
|
||||||
* are their aliases if any, or their original unminified property names
|
* are their aliases if any, or their original unminified property names
|
||||||
|
@ -240,11 +232,6 @@ export interface DirectiveDefArgs<T> {
|
||||||
*/
|
*/
|
||||||
inputs?: {[P in keyof T]?: string};
|
inputs?: {[P in keyof T]?: string};
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Remove per https://github.com/angular/angular/issues/22591
|
|
||||||
*/
|
|
||||||
inputsPropertyName?: {[P in keyof T]?: string};
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of output names.
|
* A map of output names.
|
||||||
*
|
*
|
||||||
|
|
|
@ -19,7 +19,7 @@ NgForOf.ngDirectiveDef = defineDirective({
|
||||||
factory: () => new NgForOfDef(
|
factory: () => new NgForOfDef(
|
||||||
injectViewContainerRef(), injectTemplateRef(),
|
injectViewContainerRef(), injectTemplateRef(),
|
||||||
directiveInject(IterableDiffers, InjectFlags.Default, defaultIterableDiffers)),
|
directiveInject(IterableDiffers, InjectFlags.Default, defaultIterableDiffers)),
|
||||||
features: [NgOnChangesFeature],
|
features: [NgOnChangesFeature()],
|
||||||
inputs: {
|
inputs: {
|
||||||
ngForOf: 'ngForOf',
|
ngForOf: 'ngForOf',
|
||||||
ngForTrackBy: 'ngForTrackBy',
|
ngForTrackBy: 'ngForTrackBy',
|
||||||
|
|
|
@ -45,8 +45,7 @@ describe('lifecycle hooks', () => {
|
||||||
factory: function LifecycleComp_Factory() { return new LifecycleComp(); },
|
factory: function LifecycleComp_Factory() { return new LifecycleComp(); },
|
||||||
template: function LifecycleComp_Template(ctx: $LifecycleComp$, cm: $boolean$) {},
|
template: function LifecycleComp_Template(ctx: $LifecycleComp$, cm: $boolean$) {},
|
||||||
inputs: {nameMin: 'name'},
|
inputs: {nameMin: 'name'},
|
||||||
inputsPropertyName: {nameMin: 'nameMin'},
|
features: [$r3$.ɵNgOnChangesFeature({nameMin: 'nameMin'})]
|
||||||
features: [$r3$.ɵNgOnChangesFeature]
|
|
||||||
});
|
});
|
||||||
// /NORMATIVE
|
// /NORMATIVE
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,7 +30,7 @@ describe('define', () => {
|
||||||
static ngDirectiveDef = defineDirective({
|
static ngDirectiveDef = defineDirective({
|
||||||
type: MyDirective,
|
type: MyDirective,
|
||||||
factory: () => new MyDirective(),
|
factory: () => new MyDirective(),
|
||||||
features: [NgOnChangesFeature],
|
features: [NgOnChangesFeature()],
|
||||||
inputs: {valA: 'valA', valB: 'valB'}
|
inputs: {valA: 'valA', valB: 'valB'}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -420,7 +420,7 @@ describe('di', () => {
|
||||||
type: IfDirective,
|
type: IfDirective,
|
||||||
factory: () => new IfDirective(injectTemplateRef(), injectViewContainerRef()),
|
factory: () => new IfDirective(injectTemplateRef(), injectViewContainerRef()),
|
||||||
inputs: {myIf: 'myIf'},
|
inputs: {myIf: 'myIf'},
|
||||||
features: [PublicFeature, NgOnChangesFeature]
|
features: [PublicFeature, NgOnChangesFeature()]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1987,9 +1987,8 @@ describe('lifecycles', () => {
|
||||||
type: Component,
|
type: Component,
|
||||||
tag: name,
|
tag: name,
|
||||||
factory: () => new Component(),
|
factory: () => new Component(),
|
||||||
features: [NgOnChangesFeature],
|
features: [NgOnChangesFeature({b: 'val2'})],
|
||||||
inputs: {a: 'val1', b: 'publicName'},
|
inputs: {a: 'val1', b: 'publicName'}, template
|
||||||
inputsPropertyName: {b: 'val2'}, template
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -2007,9 +2006,8 @@ describe('lifecycles', () => {
|
||||||
static ngDirectiveDef = defineDirective({
|
static ngDirectiveDef = defineDirective({
|
||||||
type: Directive,
|
type: Directive,
|
||||||
factory: () => new Directive(),
|
factory: () => new Directive(),
|
||||||
features: [NgOnChangesFeature],
|
features: [NgOnChangesFeature({b: 'val2'})],
|
||||||
inputs: {a: 'val1', b: 'publicName'},
|
inputs: {a: 'val1', b: 'publicName'}
|
||||||
inputsPropertyName: {b: 'val2'}
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2397,7 +2395,7 @@ describe('lifecycles', () => {
|
||||||
tag: name,
|
tag: name,
|
||||||
factory: () => new Component(),
|
factory: () => new Component(),
|
||||||
inputs: {val: 'val'}, template,
|
inputs: {val: 'val'}, template,
|
||||||
features: [NgOnChangesFeature]
|
features: [NgOnChangesFeature()]
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue